Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Negating the null conditional operator returns unexpected results for nothing

We encountered unexpected behavior with the null conditional operator if the variable value is Nothing.

The behavior of the following code keeps us a bit confused

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

The expected behavior is that Not l?.Any() is truthy if l has no entry or if l is Nothing. But if l is Nothing the result is falsy.

This is the test code we used to see the actual behavior.

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

Results:

  • Nothing is falsy
  • Not Nothing is truthy
  • Nothing?.Any() is falsy
  • Not Nothing?.Any() is falsy

Why isn't the last if evaluating to true?

C# prevents me from writing this kind of check altogether...

like image 601
Stephael Avatar asked Oct 17 '17 10:10

Stephael


1 Answers

In VB.NET Nothing is not equal or unequal to anything else(similar to SQL), as opposed to C#. So if you compare a Boolean with a Boolean? which has no value the result will neither be True nor False, instead the comparison will return Nothing too.

In VB.NET nullable without value means an unknown value, so if you compare a known value with an unknown value the result is also unknown, not true or false.

What you could do is to use Nullable.HasValue:

Dim result as Boolean? = l?.Any()
If Not result.HasValue Then
    'do something
End If 

Related: Why is there a difference in checking null against a value in VB.NET and C#?

like image 113
Tim Schmelter Avatar answered Nov 12 '22 19:11

Tim Schmelter