我认为C#语言可以真正用一个新的操作符来处理这种逻辑 - 这是相当常见的,而且一个操作符将简化无数行代码。
我们需要类似于 "?? "或 "if null then" 操作符,但它作为一个带有 "if not null" 条件的特殊 '.' 点运算符。对于 "?? ",第一个 "?" 就像 "?:" if-then 的 'if' 部分,而第二个 "?" 表示可空类型的 'null'。我认为我们需要一个 ".?" 运算符,它的工作方式与 "." 完全相同,只是如果左表达式为空,则它将简单地计算出 null 而不是抛出异常。我想它会是一个 "dot not null" 运算符(好吧,也许 ".!?" 更合理,但让我们不要去那里)。
因此,您如此常见的示例可以像这样去掉冗余的符号名称:
var a = long_expression.?Method()
有大量的C#代码中存在嵌套的空值检查,这些代码可以从中受益。想象一下,如果代码能够像这样:
if (localObject != null)
{
if (localObject.ChildObject != null)
{
if (localObject.ChildObject.ChildObject != null)
localObject.ChildObject.ChildObject.DoSomething();
}
}
可以简单地变成:
localObject.?ChildObject.?ChildObject.?DoSomething()
还有很多代码缺少应该存在的空值检查,导致偶尔出现运行时错误。因此,默认情况下使用新的“.? ”运算符将消除此类问题...或许不幸的是,我们无法在这一点上扭转 "." 和 ".?" 的行为,因此仅当左侧为空时,新的 ".?" 才会抛出异常——这将是更加清晰和合乎逻辑的方法,但破坏性变化非常糟糕。虽然,人们可以认为这种特定的变化可能会解决很多隐含的问题,并且不太可能破坏任何东西(只有期望引发 null 引用异常的代码)。哦,好吧...人们总是可以梦想...
唯一的缺点确实是检查 null 会稍微降低一些性能,这绝对是 "." 不检查 null 的原因。但我真的认为,如果你关心性能(并知道左侧永远不会为空),只需使用 ' .?' 就是更好的选择。
同样的,让 'for each' 检查并忽略空集合也会更好。不再需要将大多数 'for each' 语句包装在“if(collection != null)”中,或者更糟糕的是,养成始终使用空集合而不是 null 的共同习惯...在某些情况下,这样做是可以接受的,但是当在复杂的对象树中进行操作并且大多数集合为空时,这会比空值检查更糟糕(我见过很多这样的情况)。我认为,不检查 null 以提供更好的性能的良好意图在大多数情况下都产生了反作用。
Anders,现在引入这些变化并添加编译器开关永远不会太迟!
var a = temp ? null : temp.Method();
我认为你的意思是var a = temp == null ? null : temp.method();
不过这只是一个小细节。 - Sephallia>>=
用于Maybe
monad。 - Jon Purdy