请考虑以下代码,该代码使用两个略微的不同方法来检查_instance
并在尚未设置时分配它。
class InstantiationTest
{
private Object _instance;
public void Method1() {
if(_instance == null) {
_instance = new Object();
}
}
public void Method2() {
_instance = _instance ?? new Object();
}
}
VS或Resharper不断为我的显式空检查加下划线,并提示我使用null-coalescing运算符进行重构。
我想知道编译器是否足够聪明,可以在Method2()
中检测到_instance
被重新分配给自己(实际上是nop?)并将Method2()
重写为{{}}的案例。 {1}}。
我发现事实并非如此:
Method1()
对:
Test.Method1:
IL_0000: ldarg.0
IL_0001: ldfld UserQuery+Test._instance
IL_0006: brtrue.s IL_0013
IL_0008: ldarg.0
IL_0009: newobj System.Object..ctor
IL_000E: stfld UserQuery+Test._instance
IL_0013: ret
我的问题是为什么?
在编译器级别实现是否有点棘手,是否值得付出实施的努力,或者我缺少的东西?
答案 0 :(得分:5)
通常,C#编译器对IL的优化很少,只能将其留给JIT,这样可以更好地优化特定体系结构。所以它根本没有在编译器中实现,因为这需要时间远离其他事情。