1

I would like to code in VB the equivalent of this in C#:

bool? a = whatever;
bool b= (a==true);

VB compiler does not accept this:

Dim a As Boolean?
Dim b As Boolean = (a = True)

I suppose in this context, it interprets (a = True) as an affectation while I want it to be interpreted as an expression. (a == True) is apparently a syntax error.

MatSnow
  • 7,357
  • 3
  • 19
  • 31
A.D.
  • 1,062
  • 1
  • 13
  • 37
  • 1
    You mean `bool? a = true; bool b = (a == true);` The value needs to be assigned. In VB.Net it can be `Dim a As Boolean? = True Dim b As Boolean = (a.Value = True)`. But you should test `a.HasValue` first. – Jimi Jan 17 '19 at 08:59
  • 2
    In C# if you compare a Nullable with a non-Nullable the result is a non-nullable. In VB.NET the result is a Nullable. That's why you can't assign it to a non-Nullable variable. The reason is that the VB.NET designer said, if `Nothing` means _"i don't know what this is"_ then every comparison's result is also unknown ([related](https://stackoverflow.com/questions/15524045/why-is-there-a-difference-in-checking-null-against-a-value-in-vb-net-and-c)) – Tim Schmelter Jan 17 '19 at 09:15

3 Answers3

3

You can use the GetValueOrDefault-method:

Dim a As Boolean?
Dim b As Boolean = a.GetValueOrDefault()
MatSnow
  • 7,357
  • 3
  • 19
  • 31
0

You could also use CBool

Dim a As Boolean?
Dim b As Boolean = CBool(a = True)
preciousbetine
  • 2,959
  • 3
  • 13
  • 29
  • This throws a `System.InvalidOperationException` if `a` is `Nothing` – MatSnow Jan 17 '19 at 10:20
  • @MatSnow The default value of a boolean is `False`. So there is no way it is going to be `Nothing` except it was manually set to `Nothing` – preciousbetine Jan 17 '19 at 10:58
  • 1
    Nullable Booleans can be *null*, (no value has been set). You should change the code to `Dim b As Boolean = If(a.HasValue, a.Value = True, False)`. – Jimi Jan 17 '19 at 11:18
  • @preciousbetine Yes the default value of a `Boolean` is `False` and yes it can't be `Nothing`, but no it can't be set to `Nothing`. `Dim a As Boolean = Nothing` will run, but it assigns the default value to `a`, means `False`. (see the anser [here](https://stackoverflow.com/a/4804371/2967965)) - But `a` is a nullable boolean (`Boolean?`) so it **can** be `Nothing`. That's the whole point of the question. Try to run your code and you'll see what I mean... – MatSnow Jan 17 '19 at 11:20
-1

You need to be careful with the differences between 0, Nothing, and vbNull. 0 is a default value for a Boolean. vbNull is a reserved Null value which should translate as 1. Nothing will throw an exception in almost all circumstances.

Dim a As Boolean? = Nothing
Dim b As Boolean? = vbNull
Dim c As Boolean = vbNull
Dim d As Boolean

Print(a = True) 'will throw an Exception
Print(b = True) 'will return True (as vbNull = Int(1))
Print(c = True) 'will return True as the ? is unnecessary on a Boolean as vbNull = Int(1)
Print(d = True) 'will return False as the default value of a Boolean is 0
Print(a.GetValueOrDefault) 'will return False as this handles the Nothing case.

When working with unassigned values you should always check for Nothing first (or just follow good practice and set the value before you use it).

    Dim a As Boolean?
    Dim b As Boolean = IIf(IsNothing(a), False, a)

This will return False if a is Nothing, otherwise return A.

Only after testing for Nothing can you test for vbNull, as Nothing returns an error on all values. The code below will return False if Nothing or vbNull, or a otherwise.

    Dim a As Boolean?
    Dim b As Boolean = IIf(IsNothing(a), False, IIf(a = vbNull, False, a))

Note: you cannot use the code below as the test a = vbNull will be against Nothing which will throw an Exception.

Or(IsNothing(a), a = vbNull) 

I would also avoid using GetValueOrDefault in any real application, as when you start using more complicated data types the default won't be so simple and you can get unexpected results. It's far better IMHO to test for IsNothing (or Object = Nothing, Object Is Nothing) than to rely on quirks of a datatype.

Best practice would be to ensure a has a value, which you can do using

    Dim a As Boolean? = New Boolean()
    Dim b As Boolean = a

The reason I say this is the best practice is because it translates to all Classes, not just Booleans. Noted that this is overkill for Booleans.

Hope this helps.

krizcillz
  • 19
  • 3
  • Why are you bringing up `vbNull` when the original question didn't ask about it and has nothing to do with it? Also, I would strongly recommend to discontinue use of `IIf` due to type safety issues---you should prefer the ternary `If` which did not exist in VBA when the `IIf` function was introduced---and the `IsNothing` function which should be replaced with `Is Nothing`. I'd suggest to edit your answer to make it more useful. – Craig Jan 18 '19 at 14:53
  • As I recall, `vbNull` is an artifact of the VBA-based versions of VB, which had `Null` as a possible `Variant` value to support null values in databases. It's orthogonal to current .NET nullables and should not be mixed with them (or `Boolean` variables) directly. In fact, if you try to compile your code with `Option Strict On`, it will refuse due to trying to assign a value of type `VariantType` (vbNull) to a variable of type `Boolean?` or `Boolean`. – Craig Jan 18 '19 at 14:57
  • the OP was confused why he was getting syntax errors, hence explaining some differences in VB to C++. Noted on the 'IIFs', it was a demonstration to keep code short and readable for someone with C++ experience. All VB is "VB" based. VBA and VB.Net are extensions of VB which went out with VB6 (where I started programming 16 years ago). – krizcillz Jan 18 '19 at 20:31
  • The problem is that `vbNull` has nothing to do with OP's problems, as it only exists as a bridge to assist with porting pre-.NET software to VB.NET. It's got nothing to do with the behavior of `Nullable` and is more likely to confuse than help, especially if it's used incorrectly (i.e. using it for *anything* other than checking the value type of a `Variant`, and even then I'd suggest using `IsDbNull` instead of comparing the `VarType` to `vbNull`). – Craig Jan 18 '19 at 20:59