繁体   English   中英

C#6.0中的Monadic null检查

[英]Monadic null checking in C# 6.0

我偶然发现了一个有趣的网站,其中解决了C#6.0的一些新的(提议的)功能。 您可以在这里阅读: 可能的C#6.0功能

我觉得特别有趣的是monadic null检查(也称为null-propagation操作符 )。 根据网站,以下声明

var bestValue = points?.FirstOrDefault()?.X ?? -1;

包含monadic null检查,目前使用这段代码实现:

if (points != null) 
{
  var next = points.FirstOrDefault();
  if (next != null && next.X != null) return next.X;
}   
return -1;

我的第一眼就是,嘿,这里写的是什么? 但在查看“旧”代码后,我开始喜欢它了。

但是,我也开始提出一些问题,我想问一下。

  • 我假设这个null传播的运算符是线程安全的。 但这实际上是如何进行的? 种族条件会被删除还是会持续存在?
  • 该运算符如何处理泛型类型? 而且,它如何处理无约束的泛型类型? 例如,考虑一下

     var resultAfterNullCheck = x?.Y; 

    如果这里的类型Y用引用类型,非可空值类型和可空值类型实例化,那么就没有任何合理的做法(因为我不知道该怎么做,因为我根本不知道该怎么做)。 那么是否会返回默认值? 或者它会抛出错误?

  • 在查看站点提供的示例(以及我在上面复制的示例)时,我假设null-propagation运算符的一个主要好处是它只会评估语句一次。 然而(也许是由于我对CLR的了解不足),我很好奇它是如何进行的。
    对我来说,第一个评估(如果points等于null)应该触发扩展方法FirstOrDefault()在points不为null时触发,然后将返回类型的evalation设置为null或者不是,否则,X将是回来。 那么这些实际上是三个评估合二为一? 或者我不正确地理解它? 这会影响执行速度吗?

换句话说,什么会更快,执行空检查的旧方法,或这个新的可爱运算符? 我将在Visual Studio 2015下载完成后立即通过执行一些研究来检查这一点...但这需要一点耐心......

对这种新的操作员类型有什么想法吗? 它真的还是一个提议的,或者我们真的可以期望使用这个新的monadic null检查吗?

编辑
正如Matthew Watson提供了一篇很好的MSDN讨论这个(以及更多)主题的文章 ,我很好奇它是否提到了我之前关于无约束泛型的问题以及该运算符如何处理它。 不幸的是,我还没有找到答案。 虽然我认为程序员应该试图阻止使用无约束泛型,但我仍然可以想象这有时是不可行的。 如果是这样的话,重新设计是否真的有必要?

你是在暗示这个。 你的问题一个接一个:

  1. 你为什么认为它的线程安全? 调用成员函数不是。 这只是通过预检查空值来调用成员函数,因此您只能获得与原始函数保证一样多的线程安全性。

  2. 如果您的泛型类型允许空值比较(这是此操作符将在幕后使用),则将发出代码。 如果不是,您将收到编译错误(例如,如果您要求类型为值类型)。 这涵盖了所有情况!

  3. 它被称为每个操作符,就像正常一样. 运营商。 如果你说Abc它仍然是两个级别的间接,并且使用这个新的运算符没什么不同,它只是检查空值。

真正的好处?. 是它的语义(你可以一目了然地告诉你的代码试图做什么)和短路(使代码比嵌套if短得多)。 你不会取代每一个. 在您的旧代码中?. 事实上你可能很少使用它。 但有些情况下它会很有用,比如在Linq表达式中跟随...OrDefault()操作或调用事件。

根据John Skeet在他的博客中 ,部分回答你的第一个问题,空条件运算符?. (= null传播运算符)是线程安全的。

您可以在Roslyn项目讨论中找到有关计划功能的所有信息。 你也可以尝试使用Roslyn的控制台应用程序的新功能,如nuget-package(这意味着它适用于Visual Studio 2013 <)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM