三元运算符VB vs C#:为什么什么都没有解决零?
-
30-09-2019 - |
题
我只是射击自己,想知道是否有实际原因使这种情况成为可能。
无论如何,为了方便未来的射击手的方便,这个问题可以留下来。
假设我们在vb.net中具有无效的值:
Dim i as Integer?
我们想为其分配一个值,基于条件并使用三元操作员,因为它是如此整洁和东西:
i = If(condition(), Nothing, 42)
也就是说,如果条件是 true
, ,采用无效性,否则值。
在这一点上,射击发生。由于没有明显的原因,VB编译器决定了公共基本类型 Nothing
和 Integer
是 Integer
, ,在这一点上,它默默地将陈述转化为:
i = If(condition(), 0, 42)
现在,如果您要在C#中这样做:
i = (condition()) ? null : 42;
您会立即获得编译器错误,说 <null>
与 int
. 。这很棒,因为这次我走了C#,我的脚会更健康。为了进行编译,您必须明确编写:
i = (condition()) ? null : (int?)42;
现在轮到你 能够 在VB中执行同样的操作,并获得您期望的正确零性:
i = If(condition(), Nothing, CType(42, Integer?))
但这需要首先要射击。没有编译器错误,也没有警告。就是这样 Explicit On
和 Strict On
.
所以我的问题是,为什么?
我应该把这个作为编译器错误吗?
还是有人可以解释为什么编译器以这种方式行事?
解决方案
这是因为VB Nothing
与C#的直接等同于C# null
.
例如,在C#中,此代码不会编译:
int i = null;
但是此VB.NET代码正常工作:
Dim i As Integer = Nothing
vb.net Nothing
实际上是C#的紧密匹配 default(T)
表达。
其他提示
三元操作员只能返回一种类型。
在C#中,它试图根据基于 null
和 42
. 。好, null
没有类型,因此它决定三元运算符的返回类型是 42
;一个普通的老 int
. 。然后它抱怨是因为您不能像普通的旧 int
. 。当您胁迫42 int?
, ,三元运营商将返回 int?
, , 所以 null
有效。
现在,我不知道VB,但是从MSDN引用
Assigning Nothing to a variable sets it to the default value for its declared type.
这是因为VB确定三元运营商将返回 int
(使用相同的过程c#做到了), Nothing
是 0
. 。再次胁迫 42
成为一个 int?
转 Nothing
进入的默认值 int?
, ,那是 null
, ,正如您所期望的。
我认为这与没有任何关系有关。考虑此代码:
''# 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
和 null
不是同一件事...来自MSDN:
将其分配给变量的任何内容都将其设置为其声明类型的默认值。
还
如果您提供表达式中的价值类型,那么iSnothing始终返回false。
请记住那个int?是一种无效的类型,但它仍然是值类型,而不是参考类型。
尝试将其设置为 DbNull.Value
代替 Nothing
...
在许多情况下 Nothing
将转换为默认值。使用 Nothing
与您使用的方式相同 null
您需要将其施放为正确的无效类型。
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))
发生这种情况是因为整数不是参考类型。 “没有什么”只能用于参考类型。对于分配什么的值类型,将自动转换为默认值,在整数0的情况下。
实际上,通过使用新整数在VS2015(至少)中可以使用这种情况?
前任。:
if(testint> 0,testint,new Integer?),testInt在哪里进行整数?