显式空核对与空聚合运算符的编译器评估? [英] Compiler evaluation of explicit null-check vs. null-coalescing operator?
问题描述
请考虑以下代码,它使用两种稍微不同的方法来检查 _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聚结运算符重构。
我想知道编译器是否足够智能以检测 Method2()
中的情况,其中 _instance
重新分配给自身(实际上是 nop ?)并将 Method2()
重写为 Method1()
。
我看到的并不是这样:
方法1:
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
与:
Test.Method2:
IL_0000:ldarg.0
IL_0001:ldarg。 0
IL_0002:ldfld UserQuery + Test._instance
IL_0007:dup
IL_0008:brtrue.s IL_0010
IL_000A:pop
IL_000B:newobj System.Object..ctor
IL_0010:stfld UserQuery + Test._instance
IL_0015:ret
是为什么?
在编译器级别实现是很棘手的,太麻烦了,值得付出努力,还是我错过了什么?
解决方案一般来说,C#编译器对IL进行非常少的优化,直到JIT,用于特定架构。所以它只是没有在编译器中实现,因为这将需要时间远离其他的东西。
Consider the following code, which uses two slightly different methods to check _instance
and assign it when not already set.
class InstantiationTest
{
private Object _instance;
public void Method1() {
if(_instance == null) {
_instance = new Object();
}
}
public void Method2() {
_instance = _instance ?? new Object();
}
}
Either VS or Resharper keeps underlining my explicit null checks, and prompting me to refactor using the null-coalescing operator.
I wondered whether the compiler is smart enough to detect the case in Method2()
where _instance
is reassigned to itself (effectively a nop?) and rewrite Method2()
into Method1()
.
I see this is not actually the case:
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
versus:
Test.Method2:
IL_0000: ldarg.0
IL_0001: ldarg.0
IL_0002: ldfld UserQuery+Test._instance
IL_0007: dup
IL_0008: brtrue.s IL_0010
IL_000A: pop
IL_000B: newobj System.Object..ctor
IL_0010: stfld UserQuery+Test._instance
IL_0015: ret
My question is why?
Is it tricky to implement at the compiler level, too trivial to be worth the effort of implementation, or something I'm missing?
解决方案 Generally, the C# compiler does very little optimizing of the IL, leaving that up to the JIT, which optimizes things much better for a specific architecture. So it's simply not been implemented within the compiler, as that would take time away from other things.
这篇关于显式空核对与空聚合运算符的编译器评估?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!