是?? 运算符保证只运行左侧参数一次?

noe*_*cus 1 .net c#

例如,给定此代码:

int? ReallyComplexFunction()
{
    return 2; // Imagine this did something that took a while
}

void Something()
{
    int i = ReallyCleverFunction() ?? 42;
}
Run Code Online (Sandbox Code Playgroud)

...是否保证只调用一次该函数?在我的测试中,它只被调用一次,但是我看不到任何文档说明我可以依赖它总是如此.

编辑

我猜它是如何实现的,但来吧:我们是开发人员.我们不应该在猜测和假设上混淆.例如,将来所有的实现都是一样的吗?另一个平台的语言实现是否相同?这取决于语言的规格以及它提供的保证.例如,未来或不同的平台实现(不是一个好的,但它可能)可以在??实现中执行此操作:

return ReallyComplexFunction() == null ? 42 : ReallyComplexFunction();
Run Code Online (Sandbox Code Playgroud)

ReallyComplexFunction如果它没有返回,那将会调用两次null.(虽然这看起来可笑的实现,如果你有一个可为空的变量替换功能,它看起来相当合理:return a == null ? 42 : a)

如上所述,我知道在我的测试中它只被调用一次,但我的问题是C#规范是否保证/指定左侧只调用一次?如果是的话,在哪里?我在C#语言规范中看不出任何这样的提及?运算符(我最初寻找我的查询的答案).

p.s*_*w.g 9

该??运营商将评估左边一次,右边零或一次,这取决于左侧的结果.

你的代码

int i = ReallyCleverFunction() ?? 42;
Run Code Online (Sandbox Code Playgroud)

等价于(这实际上与编译器实际生成的非常接近):

int? temp = ReallyCleverFunction();
int i = temp.HasValue ? temp.Value : 42;
Run Code Online (Sandbox Code Playgroud)

或者更简单:

int i = ReallyCleverFunction().GetValueOrDefault(42);
Run Code Online (Sandbox Code Playgroud)

无论哪种方式你看它,ReallyCleverFunction只被称为一次.

  • +1用于分解可能生成的IL. (4认同)