我正在使用Nullable(Of Integer)
而刚刚被Nothing
强奸为0。那令人兴奋地使用{{1}时我不想要的东西}。
Nullable(Of Integer)
并不像我期望的那样表现。我可以通过修改它来实现我的意愿(见func1
)。但我不明白为什么这应该是必要的(我想我可能会发现很难记住这样做)。
为什么func2
没有做我想要的事情?我想我之前遇到过这种情况,我宁愿再也看不到它了。
func1
我得到的结果(在LINQPad中运行)是:
Function func1(parameter As Integer) As Nullable(Of Integer)
Return If(parameter > 10, parameter, Nothing)
End Function
Function func2(parameter As Integer) As Nullable(Of Integer)
Return If(parameter > 10, parameter, DirectCast(Nothing, Integer?))
End Function
Sub Main
' Should be True
System.Console.WriteLine(func1(11).HasValue)
System.Console.WriteLine(func2(11).HasValue)
System.Console.WriteLine()
' Should be False
System.Console.WriteLine(func1(9).HasValue)
System.Console.WriteLine(func2(9).HasValue)
End Sub
答案 0 :(得分:2)
在您的情况下重要的事实:
If
方法预计两者都是" true"和"假"表达式
必须返回相同的类型。Nothing
是类型的默认值
对于Integer
,它是0
对于参考类型,它是null
在第一种方法中,内联If
方法期望" False"表达式必须返回Integer
,因为编译器无法根据Nothing
决定返回类型,它将使用" True"生成的类型。表达。因此Nothing
将生成Integer
类型的默认值,即0
。
在第二种方法中,两个参数都显式声明了返回的类型,其中Integer
可以隐式转换为Nullable
,因此编译器将返回Nullable作为If
方法的结果。
问题中的关键角色是内联If
方法。其中使用Nothing
作为Integer
的默认值。
如果您将其重写为正常If .. Else
,那么一切都可以在没有DirectCast
Private Function GetNullableInteger(parameter As Integer) As Integer?
If parameter > 10 Then
Return parameter
Else
Return Nothing
End If
End Function
答案 1 :(得分:1)
为了解释这里发生的事情,我首先删除代码的速记部分,这可能有助于我的解释。
无法使用Null
或DBNull
分配VB.net中的整数。您可以使用Nullable-of-T分配IT。但是,只要将对象设为Nullable-ish,就可以将其评估为0。
考虑以下
dim x as Integer = nothing 'evaluates to x=0
因此,当你的函数运行时,你使用DirectCast()
返回一个nullable-ish Integer,然后func2
Function func1(parameter As Integer) As Nullable(Of Integer)
Return If(parameter > 10, parameter, Nothing)
End Function
Function func2(parameter As Integer) As Nullable(Of Integer)
Return If(parameter > 10, parameter, DirectCast(Nothing, Nullable(of Integer)))
End Function
Sub Main()
' Should be True
System.Console.WriteLine(func1(11).HasValue)
System.Console.WriteLine(func2(11).HasValue)
System.Console.WriteLine()
' Should be False
System.Console.WriteLine(func1(9).HasValue)
System.Console.WriteLine(func2(9).HasValue)
Console.ReadLine()
End Sub
答案 2 :(得分:0)
这是func1重写的。请注意,无需进行投射。
Function func1(parameter As Integer) As Nullable(Of Integer)
Dim rv As New Nullable(Of Integer)
If parameter > 10 Then
rv = parameter
End If
Return rv
End Function
If运算符If(foo,foo = true,foo = false)应该谨慎使用,因为它比标准的If结构慢。
编辑:有关If运算符的声明不正确。
感谢Chris。