Ternary operator VB vs C#: why resolves Nothing to zero?

六眼飞鱼酱① 提交于 2019-11-27 01:34:40

This is because VB's Nothing is not a direct equivalent to C#'s null.

For example, in C# this code will not compile:

int i = null;

But this VB.Net code works just fine:

Dim i As Integer = Nothing

VB.Net's Nothing is actually a closer match for C#'s default(T) expression.

The ternary operator can only return one type.

In C#, it tries to choose a type based on null and 42. Well, null doesn't have a type, so it decides that the return type of the ternary operator is that of 42; a plain old int. Then it complains because you can't return null as a plain old int. When you coerce 42 as a int?, the ternary operator is going to return an int?, so null's valid.

Now, I don't know about VB, but quoting from the MSDN,
Assigning Nothing to a variable sets it to the default value for its declared type.

Which, since VB determines that the ternary operator will return an int (using the same process C# did), Nothing is 0. Again, coercing the 42 to be an int? turns Nothing into the default value of int?, which is null, as you expected.

Mike Cheel

I am thinking this has something more to do with IF than with Nothing. Consider this code:

''#     This raises an exception
Dim x As Integer?
x = If(True, Nothing, Nothing)
MessageBox.Show(x.Value)

''#     As does 
Dim x As Integer?
x = Nothing
MessageBox.Show(x.Value)

''#     Changing one of the truthpart arguments of If is what seems to return the zero.
Dim x As Integer?
x = If(True, Nothing, 5)
MessageBox.Show(x.Value)

Why it is doing this I still don't know, probably a question for the VB team. I don't think it has to do with the Nothing keyword or Nullable.

Nothing and null are not the same thing... from the MSDN:

Assigning Nothing to a variable sets it to the default value for its declared type.

Also

If you supply a value type in Expression, IsNothing always returns False.

Keep in mind that int? is a nullable type, but it's still a value type, not a reference type.

Try setting it to DbNull.Value instead of Nothing...

In a number of cases Nothing will get converted to the default value. To use Nothing the same way you would use null you need to cast it to the correct nullable type.

Dim str As String
Dim int As Nullable(Of Integer) ' or use As Integer?
Dim reader As SqlDataReader
Dim colA As Integer = reader.GetOrdinal("colA")
Dim colB As Integer = reader.GetOrdinal("colB")
str = If(reader.IsDBNull(colA), DirectCast(Nothing, String), reader.GetString(colA))
int = If(reader.IsDBNull(colB), DirectCast(Nothing, Nullable(Of Integer)), reader.GetInt32(colB))

This happens because Integer is not a reference type. 'Nothing' is only supposed to work for reference types. For value types assigning Nothing is automatically converted to the default value, which is in the case of an Integer 0.

This is actually now possible in VS2015 (at the very least) by using New Integer?

Ex.:

If(testInt> 0, testInt, New Integer?), where testInt is of type Integer?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!