这两个代码块在功能上是相同的
if (myObj == null)
{
myObj = new MyObj();
}
Run Code Online (Sandbox Code Playgroud)
和
myObj = myObj ?? new MyObj();
Run Code Online (Sandbox Code Playgroud)
但是,使用null合并运算符的那个在myObj不为null的情况下执行不必要的赋值.但后来我想也许编译器可以优化这些自我分配.有谁知道编译器是否会注意到正在发生的事情并且基本上将底部片段转换为顶部片段?
为了进行比较,我尝试编译两者
object myObj = null;
myObj = myObj ?? new object();
Run Code Online (Sandbox Code Playgroud)
和
object myObj = null;
if(myObject == null)
{
myObj = new object();
}
Run Code Online (Sandbox Code Playgroud)
Main方法内部.(我在Mono 2.6.7上使用MonoDevelop 2.4)
如果代码按预期进行了优化,我们应该会看到生成类似的IL.这是第一个版本的IL Main:
.method public static hidebysig
default void Main (string[] args) cil managed
{
.entrypoint
.maxstack 3
.locals init (
object V_0)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: dup
IL_0004: brtrue IL_000f
IL_0009: pop
IL_000a: newobj instance void object::'.ctor'()
IL_000f: stloc.0
IL_0010: ret
}
Run Code Online (Sandbox Code Playgroud)
而对于第二个版本:
.method public static hidebysig
default void Main (string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init (
object V_0)
IL_0000: ldnull
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: brtrue IL_000e
IL_0008: newobj instance void object::'.ctor'()
IL_000d: stloc.0
IL_000e: ret
}
Run Code Online (Sandbox Code Playgroud)
所以第一个版本(使用null-coalescing运算符)产生了更多的IL.
但有两点需要注意: