显式空检查与空合并运算符的编译器评估?

问题描述 投票:0回答:1

考虑以下代码,它使用两种稍微不同的方法来检查

_instance
并在尚未设置时对其进行分配。

class InstantiationTest
{
    private Object _instance;

    public void Method1() {
        if(_instance == null) {
            _instance = new Object();
        }
    }

    public void Method2() {
        _instance = _instance ?? new Object();
    }
}

VS 或 Resharper 不断强调我的显式空检查,并提示我使用空合并运算符进行重构。

我想知道编译器是否足够聪明来检测

Method2()
中的情况,其中
_instance
被重新分配给自身(实际上是 nop?)并将
Method2()
重写为
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   

与:

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# clr cil compiler-theory
1个回答
5
投票

一般来说,C# 编译器很少对 IL 进行优化,而将其留给 JIT,JIT 可以更好地针对特定架构进行优化。所以它根本没有在编译器中实现,因为这会占用其他事情的时间。

© www.soinside.com 2019 - 2024. All rights reserved.