Why does the compiler let me cast a null to a specific type in C#?

In IL on this level, null is just null. The compiler knew it was null because that is what you wrote, as such the compiler does not need to call the cast operator at all. Casting null to an object will just yield null.

So this is a compile-time “optimization” or simplification if you will.

Since this is legal, to cast null to another object type, there is neither a warning nor an error reported from this.

Note that apparently the compiler will not do this even thought it may be able to verify that the value being cast is indeed guaranteed to be null, if it isn’t a literal.

Your example:

void Main()
{
    var s = (string)null;
    GC.KeepAlive(s);
}

IL:

IL_0000:  ldnull      
IL_0001:  stloc.0     // s
IL_0002:  ldloc.0     // s
IL_0003:  call        System.GC.KeepAlive

(I added the call to GC.KeepAlive to avoid the compiler dropping the entire variable due to it not being used anywhere.)

If I stuff the null into an object first, with no possibility of it changing:

void Main()
{
    object o = null;
    var s = (string)o;
    GC.KeepAlive(s);
}

IL:

IL_0000:  ldnull      
IL_0001:  stloc.0     // o
IL_0002:  ldloc.0     // o
IL_0003:  castclass   System.String
IL_0008:  stloc.1     // s
IL_0009:  ldloc.1     // s
IL_000A:  call        System.GC.KeepAlive

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)