我只是射击自己,想知道是否有实际原因使这种情况成为可能。
无论如何,为了方便未来的射击手的方便,这个问题可以留下来。


假设我们在vb.net中具有无效的值:

Dim i as Integer?

我们想为其分配一个值,基于条件并使用三元操作员,因为它是如此整洁和东西:

i = If(condition(), Nothing, 42)

也就是说,如果条件是 true, ,采用无效性,否则值。
在这一点上,射击发生。由于没有明显的原因,VB编译器决定了公共基本类型 NothingIntegerInteger, ,在这一点上,它默默地将陈述转化为:

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 OnStrict On.


所以我的问题是,为什么?
我应该把这个作为编译器错误吗?
还是有人可以解释为什么编译器以这种方式行事?

有帮助吗?

解决方案

这是因为VB Nothing 与C#的直接等同于C# null.

例如,在C#中,此代码不会编译:

int i = null;

但是此VB.NET代码正常工作:

Dim i As Integer = Nothing

vb.net Nothing 实际上是C#的紧密匹配 default(T) 表达。

其他提示

三元操作员只能返回一种类型。

在C#中,它试图根据基于 null42. 。好, 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#做到了), Nothing0. 。再次胁迫 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团队的问题。我认为这与无关的关键字或无关紧要的无关。

Nothingnull 不是同一件事...来自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在哪里进行整数?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top