Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
三元运算符VB vs C#:为什么不将任何内容解析为零?_C#_Vb.net_Nullable_Ternary Operator - Fatal编程技术网

三元运算符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