When I use is operator why there is only a null-check in IL code?

时光怂恿深爱的人放手 提交于 2019-12-05 00:02:38

The type of d is Derived, which is always of type Base or null. That's why the non-optimized code only checks for null.

The optimized code doesn't do a check at all because the optimizer knows that d is not null (since you assigned a new object to it) and didn't change after the assignment.

d has compile-time type Derived, so if d is non-null, it is a Derived and a Derived is always a Base because of the inheritance.

You should not use is in a case like that; it is misleading.

The usual situation with is is the opposite one, where the compile-time type is Base and you check for is Derived.

As other have said, this is because the compiler already knows for sure what's happening there. If you wrap eveything in a method and use the is operator in the opposite direction you will see something more convincing:

static void f( Base c ) {
    if ( c is Derived ) {
        Console.WriteLine( "HELLO" );
    }
}

Translates to:

.method private hidebysig static void  f(class test.Base c) cil managed
{
  // Code size       31 (0x1f)
  .maxstack  2
  .locals init ([0] bool CS$4$0000)
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  isinst     test.Derived
  IL_0007:  ldnull
  IL_0008:  cgt.un
  IL_000a:  ldc.i4.0
  IL_000b:  ceq
  IL_000d:  stloc.0
  IL_000e:  ldloc.0
  IL_000f:  brtrue.s   IL_001e
  IL_0011:  nop
  IL_0012:  ldstr      "HELLO"
  IL_0017:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_001c:  nop
  IL_001d:  nop
  IL_001e:  ret
} // end of method Program::f
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!