.NET 编译器是否允许优化 `bool result = someMethod() || true` 到 `bool 结果 = true`?

Mar*_*cka 2 .net c#

根据文档我明白

bool result = someMethod() || true;
Run Code Online (Sandbox Code Playgroud)

.NET 编译器无法优化

bool result = true; // (or actually inlined)
Run Code Online (Sandbox Code Playgroud)

换句话说,我的理解是someMethod()总是被执行。

那是对的吗?我只是在寻找确认。

Pan*_*vos 7

首先,为什么?有更好、更具表现力的方法来创建例如功能特征标志。

在 C# 中, 和&&||在左侧短路。12.14 条件逻辑运算符明确提到了这一点。

正如Sharplab.io 示例所示,该代码片段不会短路,即使在 JIT 程序集中也不会短路。

public class C {
    public void M() {
        bool result = someMethod() || true;
        Console.WriteLine(result);
        
    }
    
    bool someMethod()
    {
        return Random.Shared.Next() % 2==0;        
    }
}
Run Code Online (Sandbox Code Playgroud)

另一方面,以下调用将被消除

public class C {
    public void M() {
        bool result = true || someMethod() ;
        Console.WriteLine(result);
        
    }
    
    bool someMethod()
    {
        return Random.Shared.Next() % 2==0;        
    }
}
Run Code Online (Sandbox Code Playgroud)

C# 编译器会将其转换为:

public class C
{
    public void M()
    {
        Console.WriteLine(true);
    }

    private bool someMethod()
    {
        return Random.Shared.Next() % 2 == 0;
    }
}
Run Code Online (Sandbox Code Playgroud)


Gur*_*ron 6

是的,它总是会被执行。someMethod在一般情况下,这是不可能优化的(即删除对 的调用),因为someMethod可能会产生副作用,即更改某些静态变量、写入某些状态存储等(为 C# 选择短路方法)。

我只是在寻找确认。

除了参考文档之外:

如果 或的计算结果x || y为真,则的结果为真。否则,结果为假。如果计算结果为 true,则不进行计算。xyxy

即如果右侧决定结果,则左侧将被短路(而不是相反),即右侧被执行。

您可以运行如下所示的命令(在发布模式下):

bool result = someMethod() || true;
Console.WriteLine(result);

bool someMethod() {
    Console.WriteLine("someMethod");
    return true;
}
Run Code Online (Sandbox Code Playgroud)

这将连续打印“someMethod”和“True”。

演示@sharplab

并引用规范

  • 该操作x || y被评估为x ? true : y。换句话说,x首先评估并转换为类型bool。那么,如果xtrue,则运算结果为true。否则,y被评估并转换为 type bool,这将成为操作的结果。

  • 内联与消除调用不同。C# 规范规定必须始终进行调用 (6认同)