三元运算符VB vs C#:为什么不将任何内容解析为零?
我只是开枪打自己的脚,想知道是否有真正的原因使这种情况成为可能。三元运算符VB vs C#:为什么不将任何内容解析为零?,c#,vb.net,nullable,ternary-operator,C#,Vb.net,Nullable,Ternary Operator,我只是开枪打自己的脚,想知道是否有真正的原因使这种情况成为可能。 不管怎么说,这个问题可以留着,以方便未来的足球运动员 假设我们在vb.net中有一个可为空的值: Dim i是否为整数? 我们想根据一个条件给它赋值,并使用三元运算符,因为它是如此的简洁和有趣: i=If(条件(),无,42) 也就是说,如果条件为true,则使用可空性,否则使用值。 射击发生在哪一点。没有明显的原因,VB编译器决定Nothing和Integer的公共基类型为Integer,此时它会将语句静默地转换为: i=
不管怎么说,这个问题可以留着,以方便未来的足球运动员
假设我们在vb.net中有一个可为空的值:
Dim i是否为整数?
我们想根据一个条件给它赋值,并使用三元运算符,因为它是如此的简洁和有趣:
i=If(条件(),无,42)
也就是说,如果条件为true
,则使用可空性,否则使用值。射击发生在哪一点。没有明显的原因,VB编译器决定
Nothing
和Integer
的公共基类型为Integer
,此时它会将语句静默地转换为:
i=If(条件(),0,42)
现在,如果你在C中这样做:
i=(条件())?空:42;
您会立即收到一个编译器错误,说明
与int
的混合不好。这很好,因为如果这次我走C#路,我的脚会更健康。要编译它,您必须显式地编写:
i=(条件())?空:(int?)42;
现在,您可以在VB中执行同样的操作,并获得预期的正确空值:
i=If(条件(),无,CType(42,整数?)
但这首先需要你的脚被打中。没有编译器错误,也没有警告。这是通过显式打开
和严格打开
实现的
所以我的问题是,为什么 我应该将此视为编译器错误吗?
或者有人能解释为什么编译器会这样做吗?这是因为VB的
Nothing
与C的null
不是直接等价物
例如,在C#中,此代码不会编译:
int i = null;
但是这段VB.Net代码工作得很好:
Dim i As Integer = Nothing
VB.Net的
Nothing
实际上与C#的default(T)
表达式更接近。Nothing
和null
不是一回事。。。从MSDN:
不为变量赋值将其设置为其声明类型的默认值
也
如果在表达式中提供值类型,IsNothing将始终返回False
记住,int?是可为null的类型,但它仍然是值类型,而不是引用类型
尝试将其设置为
DbNull.Value
而不是Nothing
发生这种情况是因为Integer不是引用类型。”“Nothing”只适用于引用类型。对于值类型,不赋值将自动转换为默认值,即整数0的情况。三元运算符只能返回一种类型
在C#中,它尝试根据null
和42
选择类型。嗯,null
没有类型,因此它决定三元运算符的返回类型是42
;一个普通的老式int
。然后它会抱怨,因为不能将null作为普通的旧int
返回。当您强制42为int?
时,三元运算符将返回int?
,因此null
有效
现在,我不知道VB,但引用MSDN,不为变量赋值将其设置为声明类型的默认值。
由于VB确定三元运算符将返回一个
int
(使用与C#did相同的过程),Nothing
为0
。同样,将42
强制为int?
会将Nothing
转换为int?
的默认值,正如您所预期的那样,即null
。我认为这与IF有关,而不是与Nothing有关。考虑这个代码:
''# 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无关。在许多情况下,
Nothing
将转换为默认值。要使用Nothing
与使用null
相同的方法,需要将其强制转换为正确的可空类型
Dim str作为字符串
将整型整型设置为可为空(整型)还是将整型设置为整数?
作为SqlDataReader的Dim读取器
Dim colA作为整数=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,null(整数)),reader.GetInt32(colB))
在VS2015中,通过使用新的整数,这实际上是可能的(至少是可能的)
例:
如果(testInt>0,testInt,New Integer?),其中testInt的类型是Integer
因为,正如你所发现的,VB是一种可怕的语言,它会做一些你没有要求它去做的随机事情,这是一种误导性的帮助。@cdhowie-除非你已经尝试了几周以上,否则不要去敲它。VB.Net已经从vb6发展了很长一段路。@Joel:我同意这一点,但一个擦得锃亮的大便仍然是一个大便。:)@任何没有学会一门新语言的特殊功能的人都会发现这种语言令人沮丧。任何将这种挫折归咎于语言的人都需要重新考虑他们的反应。@Alex Nah,我是使用过很多不同语言的人之一。我开始用C64Basic编程,从那时起我开始使用VB1,最终使用VB4、5、6和.NET。这并不是说我没有接触过VB块,这使它成为我的语言,就像其他人一样。我受够了它的废话,知道为什么我不喜欢它。是的,它是一个打字错误。现在就修好了。哎哟,在那几秒钟里,我还以为我要修好很多代码呢!这就解释了为什么
inti=null代码>不起作用,但是如果int?i=0代码>和int?i=null
两者都起作用,为什么是doe