13

Let's define this function :

Public Function Test(ByVal value As Boolean)
    Return "blabla" + If(value = Nothing, "", If(value, "1", "0"))
End Function

I want it to do the following : Test(True) -> "blabla1", Test(False) -> "blabla0", Test(Nothing) -> "blabla".

Problem is that Test(Nothing) returns "blabla0".

Arthur Rey
  • 2,990
  • 3
  • 19
  • 42
  • It's a bad idea to use a Boolean for 3 values. Consider changing the method – Marvin Smit Nov 12 '13 at 14:25
  • 2
    I don't mean to use it for 3 values, i just get boolean value from a database, i'm just handling the case where pulling failed – Arthur Rey Nov 12 '13 at 14:40
  • @Arty: To check for a null from a database result, you check if the value (type `Object`, not `Boolean`) is `DBNull`, or use the `DataReader.IsDBNull` method. – Guffa Nov 12 '13 at 14:42
  • You're thinking of null terms of C# or Java. In that context there are three values - True, False or Null (like a tri-state checkbox). However that's not the way Nothing works in Visual Basic. In VB False is Nothing in the context of a boolean. Similarly String.Empty is Nothing in the context of a string. It's confusing but it's not equivalent to null in C# or Java. – phn Nov 16 '20 at 09:57

3 Answers3

21

A Boolean value can never be null (Nothing), the values that are possible are True and False. You need a nullable value, a Boolean?, for it to be able to be null.

Use the HasValue and Value properties of the nullable value to check if there is a value, and get the value:

Public Function Test(ByVal value As Boolean?)
  Return "blabla" + If(Not value.HasValue, "", If(value.Value, "1", "0"))
End Function
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
9

Boolean is a value type, not a reference type. Therefore, the value of a Boolean variable can never be Nothing. If you compare a Boolean to Nothing, VB.NET first converts Nothing to the default value for a Boolean, which is False, and then compares it to that. Therefore, testing to see if a Boolean variable Is Nothing is effectively the same as testing to see if it equals False. If you need a Boolean which can be set to Nothing, you need to make it a Nullable(Of Boolean). There is a shortcut for that, though. To make any value type nullable, you can just add a question mark after the type, like this:

Public Function Test(ByVal value As Boolean?)
    Return "blabla" + If(value.HasValue, If(value.Value, "1", "0"), "")
End Function

As you'll notice, even with the variable being nullable, you still don't test whether or not it is null by comparing it to Nothing. It may come as a surprise, but Nullable(Of T) is actually a value type as well. So, rather than testing to see if it's Nothing, you should use it's HasValue property, as I demonstrated in the example.

Steven Doggart
  • 43,358
  • 8
  • 68
  • 105
  • The answer from Guffa is good. I selected this answer because it better explains the default behavior of "Nothing" in this context. – Mike Apr 15 '23 at 12:49
3

When testing against Nothing, you need to use the Is keyword, but you won't be able to pass your value as a Boolean since it only works on reference types.

If( value Is Nothing, "", If( value, "1", "0" ) )

It is also worth noting that Nothing defaults to the default value if it is not a reference type.

You can change your signature to expect an Object rather than a Boolean if you want to do this.

Kogitsune
  • 415
  • 4
  • 8