新 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 那么您不能简单地交换 if
和 else
部分。将 null
添加到组合中可以防止简单地使用 Not
而不管 new 运算符。
这不是运算符的错 - 这是一个可为 null 的布尔值不对称的事实。
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 那么您不能简单地交换 if
和 else
部分。将 null
添加到组合中可以防止简单地使用 Not
而不管 new 运算符。
这不是运算符的错 - 这是一个可为 null 的布尔值不对称的事实。