Ternary operator VB vs C#: why resolves Nothing to zero?
我只是开枪打自己的脚,想知道是否有真正的原因使这种情况成为可能。不管怎样,这个问题可以留到将来的脚枪手方便。
假设我们在vb.net中有一个可以为空的值:
1 | Dim i as Integer? |
我们希望根据条件和使用三元运算符为其赋值,因为它是如此的简洁和复杂:
1 | i = If(condition(), Nothing, 42) |
也就是说,如果条件为
1 | i = If(condition(), 0, 42) |
现在,如果你要用C来做这个:
1 | i = (condition()) ? null : 42; |
您会立即得到一个编译器错误,说明
1 | i = (condition()) ? null : (int?)42; |
现在,您可以在vb中执行相同的操作,并获得预期的正确的空值:
1 | i = If(condition(), Nothing, CType(42, Integer?)) |
但这首先需要你的脚被击中。没有编译器错误,也没有警告。那是关于
所以我的问题是,为什么?我应该把它当作编译器的bug吗?或者有人能解释为什么编译器是这样的吗?
这是因为vb的
例如,在C中,此代码不会编译:
1 | int i = null; |
但是这个vb.net代码工作得很好:
1 | Dim i As Integer = Nothing |
net的
三元运算符只能返回一种类型。
在C中,它试图选择基于
现在,我不知道vb,但是引用了msdn的话,
因为vb决定三元运算符返回
我认为这与中情局有更多的关系,而不是什么都没有。考虑此代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ''# 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) |
为什么要这样做,我仍然不知道,可能是VB团队的一个问题。我不认为这和关键字Nothing或Nullable有关。
Assigning Nothing to a variable sets it to the default value for its declared type.
阿尔索
If you supply a value type in Expression, IsNothing always returns False.
别忘了内特?是可以为空的类型,但它仍然是值类型,而不是引用类型。
试着把它设置为
在许多情况下,
1 2 3 4 5 6 7 | 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)) |
这在VS2015中(至少)是可以通过使用新的整数实现的。
前任。:
If(testInt> 0, testInt, New Integer?), where testInt is of type Integer?
这是因为整数不是引用类型。"Nothing"只适用于引用类型。对于值类型,赋值不会自动转换为默认值,即整数0。