奇怪的C#语法

4

我刚刚找到了这个语法:

date1 = date2?.ToString("yyyy-MM-dd") ?? date3;

当然,第一次看到这样的语法时,我并不理解它。经过调试,我明白它等同于:

if(date2 != null)
   date1 = date2.ToString("yyyy-MM-dd");
else
   date1 = date3;

我的问题是:为什么会引入这种语法,因为它根本不可读,只是节省了三行文本?

编辑:我的问题是关于 ? 操作符,而不是 ??。


1
新的语法更容易理解,我想。 - Zbidi
2
只需要花点时间理解,之后阅读会变得更容易。 - Leon Barkan
3
你指的是语法中的哪一部分?是 ?. 运算符还是 ?? 运算符? - Lee
3
这只是一种语法糖,帮助懒惰的程序员少写几行代码。 - Guy
基本上,?. 防止在 date2 为 null 且试图调用 .ToString() 时发生异常。?? 的意思是,如果左侧返回 null,则返回右侧。 - Danny Goodall
显示剩余4条评论
3个回答

11

这个语句不仅节省了3行代码,而且更易读,并且避免了一个代码块,这对于允许更复杂的LINQ查询非常重要。

你觉得这两个有什么区别?

var x = collection.Select(x => new SomeClass(x?.Property ?? "default"));

相对于:

var x = collection.Select(x => 
                               {
                                   string value = null;
                                   if (x != null)
                                   {
                                       value = x.Property;
                                   }

                                   if (value == null)
                                   {
                                       value = "default";
                                   }

                                   return new SomeClass(value);
                               }
                         );

第一个更具表现力和强大。如果你有多个属性呢?

1
x?.Property 不是要先确认 x 不为 null,才能访问 .Property 来避免空引用异常吗? - Forty3
@Forty3 是的,它有这个功能。 - Patrick Hofman

2
他们引入了?.运算符的原因与引入??运算符相同:为了缩短代码。你对?.的反对意见也可以用来反对??(对三元运算符? :的反对程度较小)。但最终我认为它是有用的(就像我认为三元运算符? :是有用的一样)。如果你知道它的含义,它是可读的。如果你不知道它的含义,任何运算符都是难以理解的。
它很有用,因为你编写的代码只有在date2是字段/局部变量/参数时才正确...如果它是一个属性,那么就保证该属性不会被读取两次(这可能非常重要,具体取决于如何计算参数)。代码将被改变为类似以下内容:
DateTime? temp = date2;
string date1 = temp != null ? temp.GetValueOrDefault().ToString("yyyy-MM-dd") : date3;

所以它可能会比你想象的更加复杂。


1
这种语法是在C# 6.0中新添加的。 ?.被称为null-conditional。 这篇microsoft article描述了C# 6.0中所有新增的特性,并列出了这个新的null-conditional操作符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接