The state machine example is a good one. It's a textbook case of unreachable code.<p>The null-checking example is not good. If the external API returns a null where you don't expect one, UnreachableException will be thrown. It doesn't matter if the documentation says it will never be null; clearly the code isn't unreachable. All you need to reach it is bad data! (InvalidDataException would be a better choice, though arguably not an ideal one.)<p>If you can write a unit test that makes your code throw UnreachableException, you almost certainly should be throwing a different exception.
> Fortunately, .NET 7 adds a new type to help us out here: UnreachableException.<p>There was an UnreachableException before .NET 7 as well.<p>Look:<p>public class UnreachableException : Exception {}
Just wanted to highlight a relevant tool i recently discovered: Sentry.<p>It's already become invaluable in my .net apps for tracking down tricky errors, especially in the new MAUI apps.<p>Caught one just yesterday where the app was trying to call an api with decimals serialized with a comma because it was on a dutch user's phone! I imagine it would've been quite the headache catching that without sentry. Integrates with most tech-stacks too, not just .net btw
For null checking I'd use the relatively new ArgumentNullException.ThrowIfNull, that automatically adds the parameter name in the exception and is a very compact and obvious way to check for null in your method parameters.<p>For enums I use ArgumentExceptions, something called this code with an invalid enum argument. I think there are some cases where Unreachable is a better error, but I'd probably be more inclined to use that for logic errors, where the code itself should not be reachable according to your understanding and reaching it would mean the code is wrong. The enums and null are cases where the arguments are unexpected, which to me is different.
I don’t think that’s a good name for this. Clearly, that code can be reached. From the name, I would expect <i>”throw new UnreachableException”</i> to be something the compiler inserts to make it more robust in the sense that, if the compiler has some bug in its control flow analysis, it throws, rather than executes the wrong code.<p>Now, for a better name? Maybe <i>ShouldNeverGetHereException</i>, but that may be seen as too whimsical.
Ignoring the subject matter entirely, it's always fun to see some snippets of C# du jour and marvel at the number of new syntactical features added since my last encounter.
seems to me they are using unreachable to mean unsupported. Also they should put a message in for the first example which should highlight the int value as that is the very first thing you are going to want to know.
If TeamId is a non-nullable string then the construction of that object should fail when TeamId is null, not at the consumption site.<p>This is exactly the issue what Rust is solving. A struct construction completes or fails. There is no weird in between state.
I think I still prefer NotImplementedException. It also covers things that <i>are</i> logically reachable but not ready for use yet. The nuance is the string argument to the ctor.
It's not like you can't define your own exceptions in C#, so you always could do what the article is saying.<p>Even if exceptions might be handy, I wouldn't use exceptions for error handling for permance reasons. Instead I have another recommendation: never have void methods and use a Result type that packages the actual value along with an IsValid and Error property. So you will always return Result<T>.<p>That way, error handling is easy and doesn't cause much performance overhead.