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编译器决定,对于共同的基类型Nothing和Integer是Integer,在该点它默默地平移语句:
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 On和Strict 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)表达式的更接近的匹配.
小智 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,如你预期.