Calling an instance method on a null reference in IL

Is it correct that an instance method can be called with a null reference in IL ..? Is there any example to show this.?

+6
null c # cil
source share
3 answers

Yes, it is possible if the method does not use this because the CLR does not perform a null check for call statements.

You will need to manually modify IL, since the C # compiler almost always generates a callvirt 1 command.

See this blog and example for more details:

Instance Methods Called by Null References

Example

 .method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 18 (0x12) .maxstack 1 .locals init ([0] class SomeClass o, [1] string hello) IL_0000: nop IL_0001: ldnull IL_0002: stloc.0 IL_0003: ldloc.0 IL_0004: call instance string SomeClass::GetHello() IL_0009: stloc.1 IL_000a: ldloc.1 IL_000b: call void [mscorlib]System.Console::WriteLine(string) IL_0010: nop IL_0011: ret } 

1 In fact, the reason the C # compiler emits a callvirt even when a simple call instruction is sufficient is to prevent instance methods from being called to null references. With this behavior of the compiler, users will get a NullReferenceException , so they avoid the strange situation of calling a method on a null pointer. Eric Gunnerson explained this on a blog a while ago: Why does C # always use callvirt? Gishu also has a nice explanation in a related question .

+10
source share

See my blog post for information.

Example IL code:

 .class Program { .method static void Main(string[] args) { .entrypoint .locals init ([0] class Program p) ldloc.0 // but wait, it still null! call instance void Program::Awesome() ret } .method instance void Awesome() { ldstr "Awesome!" call void [mscorlib]System.Console::WriteLine(string) ret } .method public specialname rtspecialname instance void .ctor() { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } 
+5
source share

The CLR does not require this; it is a detail of the language implementation. C # and VB.NET do the test. C ++ / CLI is a well-known managed language that resolves it. As long as the instance method does not refer to any members of the class, then nothing happens. If so, the NullReferenceException will raise as usual, just letting you know why.

 #include "stdafx.h" using namespace System; ref class Test { public: void Run() { Console::WriteLine("no problem"); } }; int main(array<System::String ^> ^args) { Test^ obj = nullptr; obj->Run(); return 0; } 
+3
source share

All Articles