显式空核对与空聚合运算符的编译器评估? [英] Compiler evaluation of explicit null-check vs. null-coalescing operator?

查看:214
本文介绍了显式空核对与空聚合运算符的编译器评估?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码,它使用两种稍微不同的方法来检查 _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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆