我偶然发现了一个有趣的站点,其中解决了 C# 6.0 的一些新(提议的)特性。您可以在此处阅读:Probable C# 6.0 features。
我发现特别有趣的是一元空值检查(也称为空值传播运算符?.)。根据该网站,以下声明
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() 以在 points 不为 null 时触发,然后将返回的类型评估为 null 与否,如果不是,X 将是回来。所以这些实际上是三个评价合二为一?还是我理解错误?这会影响执行速度吗?
换句话说,执行空值检查的旧方法或这个新的可爱运算符会更快吗?一旦 Visual Studio 2015 的下载完成,我将尝试通过执行一些研究来检查这一点……但这需要一点耐心……
对这种新的运算符类型有什么想法吗?它真的仍然是一个提议的,还是我们真的可以期望使用这个新的一元空值检查?
编辑
由于 Matthew Watson 提供了一篇很好的MSDN 文章来讨论这个(以及更多)主题,我很好奇它是否提到了我之前关于无约束泛型的问题以及这个运算符如何处理这个问题。不幸的是,我还没有找到答案。虽然我认为程序员应该尽量避免使用不受约束的泛型,但我仍然可以想象这有时是不可行的。如果是这样的话,是否真的需要重新设计?