Back to Roslyn

Unexpected Conditions

docs/compilers/Design/Unexpected Conditions.md

11.0.1002.2 KB
Original Source

These are guidelines for writing code that may encounter "impossible" and unexpected program conditions. Like other coding guidelines, there is value in being somewhat uniform across the code base even though we may have opinions that differ. When you have a good reason to vary from these guidelines, please add comments that explain the variance for those who come after you.

  • Use Debug.Assert(Condition) to document invariants in the code. Although these dissolve away into nothing in non-Debug builds, as an open-source project we have little control over whether our customers are running our code with Debug enabled. Therefore such assertions should not consume excessive execution time. We may consider having such assertions run in production builds in the future. If we find they are too expensive we may create work items to improve their performance.
  • If you write a switch statement that is intended to be exhaustive of the possibilities, add a default branch with throw ExceptionUtilities.UnexpectedValue(switchExpression);.
  • Similarly, if you have a sequence of if-then-else if statements that is intended to be exhaustive of the possibilities, add a final "impossible" else branch with throw ExceptionUtilities.Unreachable(); or, if is convenient to provide interesting, easy to obtain data for the diagnostic, use ExceptionUtilities.UnexpectedValue. Do this also for other situations where the code reaches a point that is "impossible".
  • Validation of preconditions in public APIs should be done with plain code. Report a diagnostic if one exists for the situation (e.g. a syntax error), or throw an appropriate exception such as ArgumentNullException or ArgumentException.
  • If you run into some other weird error case that would be fatal, throw InvalidOperationException with interesting, straightforward to get, data in the message. These should be rare and should be accompanied by a comment explaining why an Assert is not sufficient.

By following these guidelines, you should find no reason to write Debug.Assert(false). If you find that in your code consider if one of these bullets suggests a different way to handle the situation.