【问题标题】:Side effects, short circuiting, and null propagating method call operator (?.)副作用、短路和空值传播方法调用运算符 (?.)
【发布时间】:2018-12-06 18:58:39
【问题描述】:

当目标对象在条件成员访问/空传播运算符中为空,并且该成员是一个方法时,是否评估该方法的参数?

也就是说,在下面的代码中,是不是调用了g()

SomeClass x = null;
x?.Foo(g());

h() 怎么样:

SomeClass x = null;
x?.Bar($"h = {h()}");

SharpLab 将参数评估放在 if 块中,因此将被跳过。但这是否由规范或实现细节保证?

【问题讨论】:

  • 您可以只运行您已经编写的代码并快速确定是否实际调用了该方法。如果您想知道规范中关于该主题的内容,请阅读规范
  • 为什么不自己试试呢?
  • But is this guaranteed by the specification or an implementation detail?(除了 HimBromBeere 的回答)查看 C# 6.0 规范草案:docs.microsoft.com/en-us/dotnet/csharp/language-reference/… 您要查找的是“空条件运算符”部分的末尾。
  • @Servy:我确实运行了导致最后一段的代码。
  • @Servy:我很高兴 engonzo 提供了指向规范正确段落的链接,因为规范自己的目录没有,而且我永远不会考虑寻找 null-在关于一元运算符的部分中传播成员访问,这绝对是一个二元运算符。

标签: c# short-circuiting side-effects null-propagation-operator


【解决方案1】:

虽然您可以很容易地尝试是否执行g,但这里是解释原因。 null-conditional-operator 只是简单的nullcheck 的快捷方式:

"[空条件运算符]测试左边的值 null 在执行成员访问 (?.) 或索引 (?[]) 之前的操作数 手术;如果左侧操作数的计算结果为 null,则返回 null。"

因此您的代码等同于以下内容:

if(x != null)
{
    x.Foo(g());
}

【讨论】:

  • 测试并没有告诉您语言保证什么,只是告诉您当前 JIT 编译器(您正在测试)的当前实现(您正在测试)如何处理这种情况。对于可能需要跨 OS 或 .Net Framework 版本移植的任何东西,我不建议将测试作为解决方案。
  • @NetMage 没错,但问题实际上由两部分组成:what 发生和 why 它发生。第一个可以很容易地通过测试来确定——我的答案并没有真正涵盖。另一方面,我的回答主要处理第二点。
  • 实际上我认为两者都没有得到有效的回答,因为您无法判断 Linux 上的 .Net Core(甚至 Windows 上的 .Net 4.7.2 上的 C#)实际上是否等同于您的示例代码参考标准。
  • 评估参数不是成员访问的一部分,因此知道成员访问没有被执行并不能告诉我们有关参数副作用的任何信息。您应该尝试阅读整个问题,其中我说了我观察到的行为,而不是告诉我尝试它有多么容易。
猜你喜欢
  • 1970-01-01
  • 2014-07-31
  • 2015-02-26
  • 2015-12-07
  • 2020-05-09
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 2011-03-07
相关资源
最近更新 更多