C# is straightforward. If you have the following code there will be no surprises:
static void Main(string[] args)
{
Console.WriteLine(Test(null, null,null,null));
}
static bool Test(int? firstLeft, int? firstRigt, int? secondLeft, int? secondRight)
{
return firstLeft == firstRigt && secondLeft == secondRight;
}
Apparently True
will be printed as the result. Let's try to do something like this in VB:
Sub Main()
Console.WriteLine(Test(Nothing,Nothing,Nothing,Nothing))
End Sub
Function Test(FirstLeft As Integer?, FirstRight As Integer?, SecondLeft As Integer?, SecondRight As Integer?) As Boolean
Return FirstLeft = FirstRight AndAlso SecondLeft = SecondRight
End Function
Can you guess what result will be? True
? Wrong. False
? Wrong. The result will be InvalidOperationException
.
That's because the type of nullable comparison result is not Boolean
, it's Boolean?
. This mean when on either side of your comparison you have Nothing
, the result of the comparison won't be True
or False
, it will be Nothing
. No wonder when you try to combine that with other comparison results it does not go down well.
I would like to learn the most idiomatic way to rewrite this function in VB. Here is the best I can do:
Function Test(FirstLeft As Integer?, FirstRight As Integer?, SecondLeft As Integer?, SecondRight As Integer?) As Boolean
'If one value has value and the other does not then they are not equal
If (FirstLeft.HasValue AndAlso Not FirstRight.HasValue) OrElse (Not FirstLeft.HasValue AndAlso FirstRight.HasValue) Then Return False
'If they both have value and the values are different then they are not equal
If FirstLeft.HasValue AndAlso FirstRight.HasValue AndAlso FirstLeft.Value <> FirstRight.Value Then Return False
'Ok now we are confident the first values are equal. Lets repeat the excerise with second values
If (SecondLeft.HasValue AndAlso Not SecondRight.HasValue) OrElse (Not SecondLeft.HasValue AndAlso SecondRight.HasValue) Then Return False
If SecondLeft.HasValue AndAlso SecondRight.HasValue AndAlso SecondLeft.Value <> SecondRight.Value Then Return False
Return True
End Function
This works, but having seen the C# version of this code I can't shake the feeling that it can be implemented simpler. In this particular case only two pairs are compared, in other cases there may be more than two, and the code above becomes event more verbose and you are forced to extract a method for comparing two values, which feels like an overkill.
What is a more idiomatic way of comparing nullable values in VB?
Use the IsNull function to determine whether an expression contains a Null value. Expressions that you might expect to evaluate to True under some circumstances, such as If Var = Null and If Var <> Null , are always False.
If you want to use the default value of the underlying value type in place of null , use the Nullable<T>. GetValueOrDefault() method. At run time, if the value of a nullable value type is null , the explicit cast throws an InvalidOperationException.
The Nullable type allows you to assign a null value to a variable.
When you declare a variable with a nullable value type, its HasValue property has a default value of False . This means that by default the variable has no defined value, instead of the default value of its underlying value type.
Function Test(FirstLeft As Integer?, FirstRight As Integer?, SecondLeft As Integer?, SecondRight As Integer?) As Boolean
'Note the HasValue are both false, this function will return true
Return Nullable.Equals(FirstLeft, FirstRight) AndAlso Nullable.Equals(SecondLeft, SecondRight)
End Function
Nullable.Equals
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With