Monadic在C#6.0中空检查

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

我觉得特别有趣的是单调空检查(也称为空传播算子 )。 根据该网站,以下声明

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;

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

不过,我也开始提出一些问题,我想问一下。

  • 我假设这个空传播运算符是线程安全的。 但是,这是如何实际执行的? 竞赛条件会被删除还是持续?
  • 这个操作符将如何处理泛型? 而且,它将如何处理不受约束的泛型? 例如,考虑

    var resultAfterNullCheck = x?.Y;
    

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

  • 看看网站提供的示例(以及我在上面复制的示例)时,我假设空传播运算符的一个主要优点是只会对语句进行一次评估。 然而(可能是由于我对CLR的知识不足),我很好奇它是如何执行的。
    对于我来说,第一次评估(如果points等于null)应该触发当点不为空时触发扩展方法FirstOrDefault(),然后将返回类型忽略为null,否则X将会是回。 所以这些实际上是三个评估合并为一个? 或者我不正确地理解它? 这会影响执行速度吗?

  • 换句话说,什么会更快,执行空检查的旧方式,还是这个新可爱的运营商? 一旦Visual Studio 2015的下载完成,我将尝试通过执行一些研究来检查此问题......但这需要一点耐心......

    对这种新的操作符类型有任何想法吗? 它真的仍然是一个提议的,或者我们真的可以期望与这个新的monadic空检查一起工作吗?

    编辑
    正如Matthew Watson提供了一篇很好的关于这个(和更多)主题的MSDN文章,我很好奇它是否提到了我之前关于无约束泛型的问题以及这个运营商如何处理这个问题。 不幸的是,我还没有找到答案。 尽管我会假设程序员应该尽量避免使用不受限制的泛型,但我仍然可以想象这有时不可行。 如果是这样的话,重新设计是否真的有必要?


    你正在超越这一点。 一个接一个,你的问题:

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

  • 如果你的泛型类型允许空比较(这是这个操作符在幕后使用的),那么代码将被发射。 如果没有,你会得到一个编译错误(例如,如果你需要类型是一个值类型)。 涵盖所有情况!

  • 它被称为一次 - 每个操作员,就像正常一样. 运营商。 如果你说Abc它仍然是两层间接的,使用这个新的操作符没有什么不同,它只是检查空值。

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


    根据John Skeet博士的说法,为了部分回答你的第一个问题,无效条件操作符?. (=空传播运算符)是线程安全的。


    您可以在Roslyn项目讨论中找到有关计划功能的所有内容。 您还可以使用Roslyn等控制台应用程序尝试新功能,如nuget-package(这意味着它可以与Visual Studio 2013一起使用)

  • 罗斯林的讨论
  • 新的C#6.0功能和测试控制台应用程序
  • 链接地址: http://www.djcxy.com/p/13059.html

    上一篇: Monadic null checking in C# 6.0

    下一篇: Null propagation operator and foreach