At page.170 of ‘CLR via C#’:
public sealed class Program {
public Int32 GetFive() { return 5; }
public static void Main() {
Program p = null;
Int32 x = p.GetFive(); // In C#, NullReferenceException is thrown
}
}
Theoretically, the code above is fine. Sure, the variable p is null, but when calling a nonvirtual
method (GetFive), the CLR needs to know just the data type of p, which is Program. If
GetFive did get called, the value of the this argument would be null. Since the argument
is not used inside the GetFive method, no NullReferenceException would be thrown.
Pardon my stupid. I remember that CLR locate really method code by ‘this’ which always implictly appares at the first argument in method delcare, why it says ‘when calling a nonvirtual
method (GetFive), the CLR needs to know just the data type of p’ ?
The CLR doesn’t do null checks for non-virtual methods. Basically, if a method is called with the
callinstruction, the CLR does not check for a nullthispointer. In contrast, thecallvirtinstruction always checks for nullity. However, C# emits thecallvirtinstruction whether or not the method is virtual.What the passage is saying is that if the C# compiler emitted the more semantically appropriate
callinstruction rather thancallvirtinstruction for non-virtual methods, then the code in question would not throw aNullReferenceException. As I recall, the compiler team decided to almost always emit thecallvirtinstruction because it handled versioning better (also the JIT can optimize acallvirtinto acall).See http://www.pvle.be/tag/clr/