小编Kyr*_*rio的帖子

为什么C#编译器在最后一个条件调用时会删除一系列方法调用?

考虑以下类:

public class A {
    public B GetB() {
        Console.WriteLine("GetB");
        return new B();
    }
}

public class B {
    [System.Diagnostics.Conditional("DEBUG")]
    public void Hello() {
        Console.WriteLine("Hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们以这种方式调用方法:

var a = new A();
var b = a.GetB();
b.Hello();
Run Code Online (Sandbox Code Playgroud)

在发布版本中(即没有DEBUG标志),我们只会GetB在控制台上看到打印,因为Hello()编译器会忽略调用.在调试版本中,两个打印都会出现.

现在让我们链接方法调用:

a.GetB().Hello();
Run Code Online (Sandbox Code Playgroud)

调试版本中的行为保持不变; 但是,如果未设置标志,我们会得到不同的结果:两个调用都被省略,并且控制台上没有打印.快速浏览一下IL可以看出整行都没有编译过.

根据C#最新ECMA标准(ECMA-334,即C#5.0),将Conditional属性放置在方法上时的预期行为如下(强调我的):

如果在呼叫点定义了一个或多个相关的条件编译符号,则包括对条件方法的调用,否则省略该调用.(§22.5.3)

这似乎并不表示整个链应该被忽略,因此我的问题.话虽如此,微软C#6.0草案规范提供了更多细节:

如果定义了符号,则包括呼叫; 否则,省略呼叫(包括接收机的评估和呼叫的参数).

没有评估调用参数的事实已被充分记录,因为这是人们使用此功能而不是#if函数体中的指令的原因之一.然而,关于"接收器的评估"的部分是新的 - 我似乎无法在其他地方找到它,它似乎解释了上述行为.

鉴于此,我的问题是:在这种情况下,C#编译器没有评估的理由什么a.GetB() ? …

c# conditional-compilation

69
推荐指数
3
解决办法
5370
查看次数

标签 统计

c# ×1

conditional-compilation ×1