否定null条件运算符会返回意外结果

Ste*_*ael 4 vb.net null-conditional-operator

如果变量值为Nothing,我们会遇到null条件运算符的意外行为.

以下代码的行为让我们有点困惑

  Dim l As List(Of Object) = MethodThatReturnsNothingInSomeCases()
  If Not l?.Any() Then
    'do something
  End If 
Run Code Online (Sandbox Code Playgroud)

Not l?.Any()如果l没有条目或者l什么都没有,那么预期的行为是真实的.但如果l没有什么结果是假的.

这是我们用来查看实际行为的测试代码.

Imports System
Imports System.Collections.Generic
Imports System.Linq

Public Module Module1

 Public Sub Main()

  If Nothing Then
   Console.WriteLine("Nothing is truthy")
  ELSE 
   Console.WriteLine("Nothing is falsy")
  End If

  If Not Nothing Then
   Console.WriteLine("Not Nothing is truthy")
  ELSE 
   Console.WriteLine("Not Nothing is falsy")
  End If

  Dim l As List(Of Object)
  If l?.Any() Then
   Console.WriteLine("Nothing?.Any() is truthy")
  ELSE 
   Console.WriteLine("Nothing?.Any() is falsy")
  End If 

  If Not l?.Any() Then
   Console.WriteLine("Not Nothing?.Any() is truthy")
  ELSE 
   Console.WriteLine("Not Nothing?.Any() is falsy")
  End If 

 End Sub
End Module
Run Code Online (Sandbox Code Playgroud)

结果:

  • 没有什么是假的
  • 没有什么是真的
  • 没什么?.Any()是假的
  • 不是什么?.Any()是假的

如果评估为真,为什么不是最后一个?

C#阻止我完全写这种检查......

Tim*_*ter 5

在VB.NET Nothing中,与C#相反,它不等于或等于其他任何东西(类似于SQL).因此,如果您将a BooleanBoolean?没有值的结果进行比较,结果既不会True也不会False比较,而且比较也会返回Nothing.

在VB.NET中,没有值的可空值意味着未知值,因此如果将已知值与未知值进行比较,结果也是未知的,不是真或假.

你可以做的是使用Nullable.HasValue:

Dim result as Boolean? = l?.Any()
If Not result.HasValue Then
    'do something
End If 
Run Code Online (Sandbox Code Playgroud)

相关:为什么在VB.NET和C#中检查null值是否存在差异?