是否与空合并运算符"相反"?(...用任何语言?)

Jay*_*Jay 87 c# syntax programming-languages operators null-coalescing-operator

null coalescing大致翻译为 return x, unless it is null, in which case return y

我经常需要 return null if x is null, otherwise return x.y

我可以用 return x == null ? null : x.y;

不错,但null中间总是困扰我 - 这似乎是多余的.我更喜欢这样的东西return x :: x.y;,::只有在它之前的东西不是的时候才会评估null.

我认为这几乎与null合并相反,有点简洁,内联null检查,但我[ 几乎 ]确定在C#中没有这样的运算符.

是否有其他语言有这样的运营商?如果是这样,它叫什么?

(我知道我可以用C#编写一个方法;我使用return NullOrValue.of(x, () => x.y);,但如果你有更好的东西,我也希望看到它.)

Jon*_*eet 61

Groovy中有一个null-safe解引用运算符(?.)...我认为这就是你所追求的.

(它也被称为安全导航操作员.)

例如:

homePostcode = person?.homeAddress?.postcode
Run Code Online (Sandbox Code Playgroud)

这将使如果空person,person.homeAddressperson.homeAddress.postcode为空.

(现在可以在C#6.0中使用,但在早期版本中不可用)

  • 我为C#5.0提名这个功能.我不知道或不关心Groovy究竟是什么,但这足以直观地用于任何语言. (28认同)
  • 安全导航适用于发布的简单示例,但如果您打算在函数调用中使用非空值,您仍然需要使用三元运算符,例如:`Decimal?后 = 前 == 空?null : SomeMethod( pre );`。如果我可以将其减少为“十进制?post = pre :: SomeMethod( pre );”,那就太好了 (2认同)

Eri*_*ert 35

我们考虑过添加?到C#4.它没有削减; 这是一个"很高兴"的功能,而不是"必备"功能.我们将再次考虑该语言的假设未来版本,但如果我是你,我不会屏住呼吸.随着时间的推移,它不太可能变得更加重要.:-)

  • @nick:当然,实现词法分析器和解析器是五分钟的工作.然后你开始担心"智能感知引擎能处理得好吗?" 并且"当你输入错误恢复系统时它是如何处理它的?但是不是吗?" 而且"有多少不同的东西"." 无论如何,在C#中意味着什么,有多少人值得拥有?在它之前,如果你弄错了,错误信息应该是什么,以及这个功能需要多少测试(提示:很多.)我们如何记录它并传达变化,以及...... (13认同)
  • @EricLippert我认为这将是主要的"很高兴",这使得C#如此成功,并且完美地完成了使代码尽可能简洁和富有表现力的使命! (11认同)
  • @nick:回答你的问题 - 是的,实施成本是一个因素,但是一个小因素.我们工作的级别没有便宜的功能,只有或多或少的昂贵功能.价值5美元的开发工作可以使解析器在正确的代码情况下工作,很容易变成价值数万美元的设计,实现,测试,文档和教育. (2认同)
  • @AlexanderHøst:我已经快十年没有加入 C# 团队了,所以告诉我你的功能请求不太可能得到任何结果:) C# 设计过程是开源的;如果您有语言功能请求,请随时在他们的 github 网站上发布建议。 (2认同)

Eri*_*ric 16

如果你有一种特殊的短路布尔逻辑,你可以这样做(javascript示例):

return x && x.y;
Run Code Online (Sandbox Code Playgroud)

如果x为null,则不会进行评估x.y.

  • 除此之外,这也会短路 0、"" 和 NaN,因此它与 ?? 不是相反的。它与 || 相反。 (5认同)

And*_*tan 7

将此作为答案添加是正确的.

我想在C#中没有这样的东西的原因是因为,与合并运算符(仅对引用类型有效)不同,反向操作可以产生引用或值类型(即class x使用成员int y- 因此不幸的是在许多情况下无法使用

但是,我不是说我不想看到它!

该问题的潜在解决方案是操作员可以自动将右侧的值类型表达式提升为可空.但是你有一个问题,x.y即y是一个int,实际上会返回一个int?很痛苦的问题.

另一个可能更好的解决方案是,如果左侧的表达式为null,则操作符将返回右侧类型的默认值(即null或0).但是,您有一些问题可以区分实际读取零/ null的情况,x.y或者它是否由安全访问运算符提供.


48k*_*ocs 6

Delphi有:(而不是.)运算符,它是null安全的.

他们在考虑增加一个?操作员对C#4.0做同样的事情,但是得到了斩波块.

与此同时,还有IfNotNull()有哪些划痕痒.它肯定比大?或者:但它确实允许你编写一系列操作,如果其中一个成员为null,则不会对你造成NullReferenceException.