三元运算符VB vs C#:为什么解决Nothing为零?

GSe*_*erg 25 c# vb.net nullable ternary-operator

我只是在脚下射击,想知道是否有实际的理由让这种情况成为可能.
无论如何,这个问题可以留在未来的脚射手的方便.


假设我们在vb.net中有一个可以为null的值:

Dim i as Integer?
Run Code Online (Sandbox Code Playgroud)

我们希望根据条件为其分配值,并使用三元运算符,因为它非常简洁和东西:

i = If(condition(), Nothing, 42)
Run Code Online (Sandbox Code Playgroud)

也就是说,如果条件是true,则采用可空性,否则采用该值.
射击发生的时间点.没有明显的原因VB编译器决定,对于共同的基类型NothingIntegerInteger,在该点它默默地平移语句:

i = If(condition(), 0, 42)
Run Code Online (Sandbox Code Playgroud)

现在,如果您要在C#中执行此操作:

i = (condition()) ? null : 42;
Run Code Online (Sandbox Code Playgroud)

你会立即得到一个编译器错误,说<null>不能很好地混合int.这很棒,因为这次我采用C#方式,我的脚会更健康.为了编译,你必须明确地写:

i = (condition()) ? null : (int?)42;
Run Code Online (Sandbox Code Playgroud)

现在,您可以在VB中执行相同操作并获得正确的null-ness:

i = If(condition(), Nothing, CType(42, Integer?))
Run Code Online (Sandbox Code Playgroud)

但这需要首先拍摄你的脚.没有编译器错误,也没有警告.这是Explicit OnStrict On.


所以我的问题是,为什么?
我应该把它当作编译器错误吗?
或者有人可以解释为什么编译器会以这种方式运行?

Joe*_*orn 35

这是因为VB Nothing不是C#的直接等价物null.

例如,在C#中,此代码将无法编译:

int i = null;
Run Code Online (Sandbox Code Playgroud)

但是这个VB.Net代码工作得很好:

Dim i As Integer = Nothing
Run Code Online (Sandbox Code Playgroud)

VB.Net Nothing实际上是C#default(T)表达式的更接近的匹配.

  • Phew,在那里几秒钟,我以为我将不得不修复**很多代码! (2认同)

小智 12

三元运算符只能返回一种类型.

在C#中,它尝试选择基于null和的类型42.好吧,null没有类型,所以它决定三元运算符的返回类型是42; 一个普通的老人int.然后它抱怨,因为你不能返回null作为一个普通的旧int.当你强制42作为a时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,如你预期.