Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.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.net 为什么这两个代码块存储不同的值?_Vb.net_Entity Framework_Nullable - Fatal编程技术网

Vb.net 为什么这两个代码块存储不同的值?

Vb.net 为什么这两个代码块存储不同的值?,vb.net,entity-framework,nullable,Vb.net,Entity Framework,Nullable,设置: customObject是实体框架对象,customObject.is_required是一个可为空的字节字段,表示SQL Server中的一列,该列为tinyint并允许为空 ddlIsRequired是一个下拉列表,其中包含三个具有以下值的项: 空白 1表示是 0表示否 考虑以下代码: customObj.is_required = If(String.IsNullOrEmpty(ddlIsRequired.SelectedValue), _

设置:

customObject是实体框架对象,customObject.is_required是一个可为空的字节字段,表示SQL Server中的一列,该列为tinyint并允许为空

ddlIsRequired是一个下拉列表,其中包含三个具有以下值的项:

空白

1表示是

0表示否

考虑以下代码:

customObj.is_required = If(String.IsNullOrEmpty(ddlIsRequired.SelectedValue), _
                          Nothing, _
                          ddlIsRequired.SelectedValue)
执行时,上述代码行在可空字节字段customObj.is_中存储0

执行时,上面的代码块在customObj.is_required中不存储任何内容,这是我所期望的inline if所做的,然而inline if似乎将可空字节字段视为不可空,而是存储任何数字的默认值a零

这是为什么?

原因是If函数必须返回具有给定类型的值。编译器通过查看返回值(第2个和第3个参数)的两个表达式来决定返回什么类型。在您的例子中,一个值为Nothing,另一个值为String。编译器决定可以不包含任何内容或字符串的最简单类型是字符串。如果选择的值为Nothing(无),则会将其转换为字符串;如果选择了Option Strict Off(这是一个坏主意),则在将字符串分配给Byte?时会将其转换为0

如果要在一条语句中执行此操作,则必须明确返回的表达式是一个字节

原因是If函数必须返回具有给定类型的值。编译器通过查看返回值(第2个和第3个参数)的两个表达式来决定返回什么类型。在您的例子中,一个值为Nothing,另一个值为String。编译器决定可以不包含任何内容或字符串的最简单类型是字符串。如果选择的值为Nothing(无),则会将其转换为字符串;如果选择了Option Strict Off(这是一个坏主意),则在将字符串分配给Byte?时会将其转换为0

如果要在一条语句中执行此操作,则必须明确返回的表达式是一个字节


正如Blackwood所说,编译器通过检查最后两个参数的类型,自动推断三元If操作的返回类型。例如:

Dim test As Object = If(True, "1", "2")
Console.WriteLine(test.GetType().Name) ' Outputs "String"
Dim test2 As Object = If(True, 1, 2)
Console.WriteLine(test.GetType().Name) ' Outputs "Int32"
在您的例子中,第一个值是Nothing,因此编译器无法使用它来推断返回类型。然后,它查看第二个值,发现它是一个字符串,正如您在上面的注释中所述,SelectedValue属性被声明为字符串属性。因此,三元操作的返回类型将是String

因此,当它不返回任何内容时,它将以字符串类型返回,然后将其转换为可为空的字节。换句话说,从长远来看,它是这样做的:

Dim input As String = ddlIsRequired.SelectedValue
Dim stringOutput As String = Nothing
If String.IsNullOrEmpty(input) Then
    stringOutput = Nothing
Else
    stringOutput = input
End If
Dim output As Byte? = CType(output, Byte?)
customObj.is_required = output
既然在VB的CType中,字节是什么?返回0,这就是您得到的结果。只要强制使用正确的类型,您仍然可以使用三元If运算符:

customObj.is_required = If(String.IsNullOrEmpty(ddlIsRequired.SelectedValue), Nothing, CType(ddlIsRequired.SelectedValue, Byte?))
从长远来看,它是这样的:

Dim input As String = ddlIsRequired.SelectedValue
Dim inputNullableByte As Byte? = CType(input, Byte?)
Dim output As Byte? = Nothing
If String.IsNullOrEmpty(input) Then
    output = Nothing
Else
    output = inputNullableByte
End If
customObj.is_required = output
正如其他人所说,通过启用Option Strict,编译器将强制您以这种方式强制输入类型,否则它将无法编译:

Option Strict On
' ...
Dim output As Byte? = If(True, Nothing, "1") ' Compiler error BC30512 Option Strict On disallows implicit conversions from 'String' to 'Byte?'
鉴于:

Option Strict Off
' ...
Dim output As Byte? = If(True, Nothing, "1") ' Works and output gets set to 0

正如Blackwood所说,编译器通过检查最后两个参数的类型,自动推断三元If操作的返回类型。例如:

Dim test As Object = If(True, "1", "2")
Console.WriteLine(test.GetType().Name) ' Outputs "String"
Dim test2 As Object = If(True, 1, 2)
Console.WriteLine(test.GetType().Name) ' Outputs "Int32"
在您的例子中,第一个值是Nothing,因此编译器无法使用它来推断返回类型。然后,它查看第二个值,发现它是一个字符串,正如您在上面的注释中所述,SelectedValue属性被声明为字符串属性。因此,三元操作的返回类型将是String

因此,当它不返回任何内容时,它将以字符串类型返回,然后将其转换为可为空的字节。换句话说,从长远来看,它是这样做的:

Dim input As String = ddlIsRequired.SelectedValue
Dim stringOutput As String = Nothing
If String.IsNullOrEmpty(input) Then
    stringOutput = Nothing
Else
    stringOutput = input
End If
Dim output As Byte? = CType(output, Byte?)
customObj.is_required = output
既然在VB的CType中,字节是什么?返回0,这就是您得到的结果。只要强制使用正确的类型,您仍然可以使用三元If运算符:

customObj.is_required = If(String.IsNullOrEmpty(ddlIsRequired.SelectedValue), Nothing, CType(ddlIsRequired.SelectedValue, Byte?))
从长远来看,它是这样的:

Dim input As String = ddlIsRequired.SelectedValue
Dim inputNullableByte As Byte? = CType(input, Byte?)
Dim output As Byte? = Nothing
If String.IsNullOrEmpty(input) Then
    output = Nothing
Else
    output = inputNullableByte
End If
customObj.is_required = output
正如其他人所说,通过启用Option Strict,编译器将强制您以这种方式强制输入类型,否则它将无法编译:

Option Strict On
' ...
Dim output As Byte? = If(True, Nothing, "1") ' Compiler error BC30512 Option Strict On disallows implicit conversions from 'String' to 'Byte?'
鉴于:

Option Strict Off
' ...
Dim output As Byte? = If(True, Nothing, "1") ' Works and output gets set to 0

顺便问一下,SelectedValue属性的类型是什么?这是对象还是字符串属性?SelectedValue始终返回字符串。是的,但属性的类型是什么?通过对象浏览器:公共可重写属性SelectedValue as String:摘要:获取列表控件中选定项的值,或选择列表控件中包含指定值的项。返回值:列表控件中选定项的值。默认值为空字符串。异常:System.ArgumentOutOfRangeException:所选值不在可用值列表中,并且已加载视图状态或其他状态。已执行回发。有关更多信息,请参阅备注部分
顺便问一下,SelectedValue属性的类型是什么?这是对象还是字符串属性?SelectedValue始终返回字符串。是的,但属性的类型是什么?通过对象浏览器:公共可重写属性SelectedValue as String:摘要:获取列表控件中选定项的值,或选择列表控件中包含指定值的项。返回值:列表控件中选定项的值。默认值为空字符串。异常:System.ArgumentOutOfRangeException:所选值不在可用值列表中,并且已加载视图状态或其他状态。已执行回发。有关更多信息,请参阅备注部分。是的,这现在是有意义的。遗憾的是,内联if对此如此紧张。问题回答了,谢谢!打开选项STRICT还不够,您可以强制If返回一个字节吗?如果你愿意的话。我编辑了我的答案来说明我是怎么做的。我只是对option strict做了一个评论,你的意思是向其他人提出这个问题吗,也许是OP?option strict确实是开着的。没有它你永远不会离开家。它甚至不应该是一个选项,但是,嘿,它是VB。是的,这现在是有意义的。遗憾的是,内联if对此如此紧张。问题回答了,谢谢!打开选项STRICT还不够,您可以强制If返回一个字节吗?如果你愿意的话。我编辑了我的答案来说明我是怎么做的。我只是对option strict做了一个评论,你的意思是向其他人提出这个问题吗,也许是OP?option strict确实是开着的。没有它你永远不会离开家。它甚至不应该是一个选项,但是,嘿,它是VB。