I have this code:
dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)),
Nothing)
when srcCell.CELL_VALUE_FLOAT is Nothing it mysteriously evaluates to the True part!
Funny part is that a normal If statement correctly evaluates to the False part:
If (srcCell.CELL_VALUE_FLOAT IsNot Nothing) Then
dstCell.CELL_VALUE_INT = Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT))
Else
dstCell.CELL_VALUE_INT = Nothing
End If
Any ideas?
Thank u!
EDIT: CELL_VALUE_FLOAT is a Nullable(Of Double) and CELL_VALUE_INT is a Nullable(of Integer)
In Quickwatch the condition evaluates correclty to False, but when running the If() function evaluates to the True part.
Example of an If-Then statement is − If (a <= 20) Then c= c+1 End If. If the condition evaluates to true, then the block of code inside the If statement will be executed. If condition evaluates to false, then the first set of code after the end of the If statement (after the closing End If) will be executed.
When an If ... Then ... Else statement is encountered, condition is tested. If condition is True , the statements following Then are executed. If condition is False , each ElseIf statement (if there are any) is evaluated in order.
Following is the If-Then-Else statement syntax in VB.NET as follows: Syntax: If (Boolean_expression) Then. 'This statement will execute if the Boolean condition is true.
In Visual Basic, If statement is useful to execute the block of code or statements conditionally based on the value of an expression. Generally, in Visual Basic, the statement that needs to be executed based on the condition is known as a “Conditional Statement” and the statement is more likely a block of code.
when srcCell.CELL_VALUE_FLOAT is Nothing it mysteriously evaluates to the True part!
Nope, it does not. It just evalues the false part (Nothing
) as 0
, thus setting CELL_VALUE_INT
to 0.
Let me elaborate: The expression
Dim i As Integer? = If(False, 1, Nothing)
fills i
with 0
. (Test it, if you don't believe me.)
Why does this happen? Nothing
in VB.NET is not the same as null
in C#. If used with a value type, Nothing
means "the default value of that type". If
infers Integer
(not Integer?
) as the common type for 1
and Nothing
, and, thus, evaluates Nothing
as default(Integer) = 0
.
You can fix this as follows:
Dim i As Integer? = If(False, 1, DirectCast(Nothing, Integer?))
which, in your example, would mean
dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)),
DirectCast(Nothing, Integer?))
This should yield the correct value now.
Since this is quite surprising behaviour, I have filed a Microsoft Connect suggestion some time ago to add a compiler warning.
Nothing
in VB.NET is not fully equal to null
in C#
It is more like default(T)
where T is a Type.
' VB:
dim x as DateTime = DateTime.MinValue
If x Is Nothing then
Console.WriteLine("True")
End if
' C#
var x = DateTime.MinValue
if (x == default(DateTime))
Console.WriteLine("True");
if (x == null) ' throw a compile time error
And
dim x as Double = nothing ' x will be 0 (default for Double)
the build in inline if expects both return values to be the same type. So what you a really doing is:
dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)),
Convert.ToDouble(Nothing))
since the false part gets internally converted to double
and dstCell.CELL_VALUE_INT
will be 0 instead of nothing.
Try this one:
dstCell.CELL_VALUE_INT = If(srcCell.CELL_VALUE_FLOAT IsNot Nothing,
Ctype(Math.Round(CDbl(srcCell.CELL_VALUE_FLOAT)), Integer?),
Nothing)
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