UPDATE: this question was t he was the subject of my blog on July 17, 201 . 2. Thanks for the great question!
Why does the compiler not find out that my code is 100% sure that it is an exception at runtime and thus produces a compile-time error?
Why should the compiler make code that is guaranteed to depend on a compile-time error? Wouldn't that do:
int M() { throw new NotImplementedException(); }
into a compile-time error? But this is the exact opposite of what you want; you want this to be a runtime error to compile incomplete code.
Now you can say: well, dereferencing zeros is always undesirable always, while the exception "not implemented" is clearly desirable. So can the compiler detect only this particular situation when a null ref exception is thrown and give an error?
Of course available. We just need to spend a budget on implementing a data flow analyzer that tracks when a given expression is always null, and then makes it a compilation time error (or warning) to dereference this expression.
The questions to answer are as follows:
- How much does this feature cost?
- How much benefit does the user receive?
- Is there any other opportunity that has a better cost-benefit ratio and provides the user with more benefits?
The answer to the first question is "pretty much" - road code flow analyzers for design and build. The answer to the second question is "not very many" - the number of situations in which you can prove that null will be dereferenced is very small. The answer to the third question over the past twelve years has always been yes.
Therefore, there is no such function.
Now you can say that C # has a limited ability to detect when an expression is always / never non-zero; a zero arithmetic analyzer uses this analysis to create a more optimal zero arithmetic code (*), and obviously, a flow analyzer uses it to determine reachability. So, why not just use an existing error and flow analyzer to detect when you always dereferenced the zero constant?
That would be cheap to implement, of course. But the corresponding user benefit is now tiny. How many times in real code do you initialize a constant to zero, and then cast it? It seems unlikely that anyone will really do this.
Moreover: yes, it is always better to detect an error at compile time instead of runtime, because it is cheaper. But the error here - guaranteed zero dereferencing - will be detected during the first testing of the code and subsequently fixed.
Thus, the main function request here is to detect a very improbable and accusatory incorrect situation during compilation, which will always be immediately detected and corrected the first time the code is run. Therefore, this is not a good candidate for spending the budget on its implementation; we have many priorities.
(*) See a long series of articles on how the Roslyn compiler does this, which starts at http://ericlippert.com/2012/12/20/nullable-micro-optimizations-part-one/