新 C#/VB – 首次引入条件不对称?

New C#/VB – first asymmetry in conditions introduced?

C# 大佬们见谅VB,不过下面的内容应该和这两种语言都有关系。 编辑: 它是相关的,但到目前为止没有人注意到 C# 和 VB 评估 不同 。问题已调整。

以前,如果我们有简单的

If condition Then
    ThenPart()
Else
    ElsePart()
End If

想把它重新排列成倒序,我们交换了ThenPart()ElsePart()并否定了条件(一般来说,通过使用Not(condition))。可以重新安排每个条件。

最近介绍了很棒的Null-conditional Operators。与他们一起出现了不对称的情况。 您不能再与他们一起使用 Not(condition)。还是我忽略了什么?(这是问题。)

尝试在此处将 ThenPart()ElsePart() 重新排列为相反的顺序:

Dim list As List(Of Integer) = Nothing
If list?.Count > 0 Then
    ThenPart()
Else
    ElsePart()
End If

诀窍是空值出现在条件中,当然,它不能用Not取反。因此你不能使用平凡的否定 If Not(list?.Count = 0) 也不能使用 If list?.Count <= 0.

唯一的方法是老式的 If list Is Nothing OrElse list.Count = 0.(完全否定将使用 <= 0)(编辑:仅适用于 VB . VB 和 C# 在这里出现分歧,见下文。)

简单地否定每个运算符的琐碎时间已经不复存在(编辑:仅在 VB 中)。还是我忽略了什么?


进一步研究后:

它看起来在 C# 中你可以安全地做 !(list?.Count = 0) 并且在这个发现之后,C# 摆脱了这个问题。这里没有不对称,你可以像以前一样取反。但据我所知,VB 的不对称性仍然存在,因为 null evaluation in Visual Basic 类似于 ANSI SQL – 空值通过表达式传播。所以在 VB 中,你不能比 If list Is Nothing OrElse list.Count = 0 更简单地否定 list?.Count > 0。 (这就是我使用单词 'asymmetry' 的原因。)还是我忽略了什么?

你应该能够很好地否定条件:

 if (!(list?.Count > 0))...

但是否定形式没有缩写形式(你必须接受扩展形式)。

关于将否定移动到条件中没有什么新鲜事(除了你把 x != null && x.Count > 0 写成 x?.Count > 0 的更短的方式) - 同样的 Morgan laws 适用于否定。

原始条件(A 和 B):

 list != null && list.Count > 0 

否定(不是A或不是B):

 list == null || list.Count <= 0

请注意,对于可空值,C# 5 中存在类似的行为 - 如果您仅否定操作(如 ><=),您会得到错误的结果:

int? v = null;
Console.WriteLine(v1 > 1); // false
Console.WriteLine(!(v1 > 1)); // negated, so true
Console.WriteLine(v1 <= 1); // just > negated - false.

Trivial times where it was simple to negate every operator are gone.

没有任何变化 - 如果在您的第​​一个示例中 condition 可以 return null 那么您不能简单地交换 ifelse 部分。将 null 添加到组合中可以防止简单地使用 Not 而不管 new 运算符。

这不是运算符的错 - 这是一个可为 null 的布尔值不对称的事实。