0

C# 的家伙会原谅我的 VB,但以下应该与这两种语言有关。编辑:它是相关的,但到目前为止没有人注意到 C# 和 VB 评估不同。问题调整。

以前,如果我们有简单的

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

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

最近,引入了很棒的空条件运算符。随之而来的是不对称性。您不能再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 中的不对称性仍然存在,因为nullVisual Basic中的求值类似于 ANSI SQL——空值通过表达式传播。所以在 VB 中,你不能list?.Count > 0If list Is Nothing OrElse list.Count = 0. (这就是我使用“不对称”这个词的原因。)还是我忽略了什么?

4

2 回答 2

3

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

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

但是否定的形式没有简短的形式(您必须使用扩展形式)。

将否定转化为条件并没有什么新鲜事(除非你有更短的写作方式x != null && x.Count > 0as x?.Count > 0)——同样的摩根定律也适用于否定。

原始条件(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.
于 2015-08-10T22:01:52.377 回答
3

简单地否定每个运算符的琐碎时代已经一去不复返了。

什么都没有改变——如果condition在你的第一个例子中可以返回 null 那么你不能简单地交换ifelse部分。添加null到混合中可以防止简单地使用Not新的运算符。

这不是操作员的错 - 这是一个可为空的布尔值不对称的事实。

于 2015-08-10T22:04:20.907 回答