考虑以下代码:
var str = (string)null;
Run Code Online (Sandbox Code Playgroud)
编写代码时,这是我的IL代码:
IL_0001: ldnull
Run Code Online (Sandbox Code Playgroud)
并且IL有任何Cast操作符但是:
var test = (string) new Object();
Run Code Online (Sandbox Code Playgroud)
该IL代码是:
IL_0008: castclass [mscorlib]System.String
Run Code Online (Sandbox Code Playgroud)
所以Casting nullto string被忽略了.
为什么编译器允许我转换null为特定类型?
ang*_*son 47
在IL这个级别上,null就是null.编译器知道这是null因为这是你写的,因此编译器根本不需要调用转换操作符.投射null到一个物体只会屈服null.
因此,如果您愿意,这是编译时的"优化"或简化.
由于这是合法的,要转换null为另一个对象类型,既没有警告也没有报告错误.
请注意,显然编译器不会这样做,即使它可能能够验证正在投射的值确实是保证的null,如果它不是文字的话.
你的例子:
void Main()
{
var s = (string)null;
GC.KeepAlive(s);
}
Run Code Online (Sandbox Code Playgroud)
IL:
IL_0000: ldnull
IL_0001: stloc.0 // s
IL_0002: ldloc.0 // s
IL_0003: call System.GC.KeepAlive
Run Code Online (Sandbox Code Playgroud)
(我添加了调用以GC.KeepAlive避免编译器丢弃整个变量,因为它没有在任何地方使用.)
如果我null先填入一个对象,不可能改变它:
void Main()
{
object o = null;
var s = (string)o;
GC.KeepAlive(s);
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Njo*_*jol 19
在Java中,至少有一种情况需要将null某个类型转换为某种类型,这就是使用重载方法告诉编译器要执行哪种方法(我假设在C#中也是这种情况).由于null是0(或任何指针null代表)不管是什么类型是你不会看到任何编译的差别,但(除了那些方法被调用).