奇怪的互动"如果"和Nullable(整数)

时间:2016-12-15 10:01:49

标签: vb.net nullable conditional-operator

我正在使用Nullable(Of Integer)而刚刚被Nothing强奸为0。那令人兴奋地使用{{1}时我不想要的东西}。

下面的{p> 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

3 个答案:

答案 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)

为了解释这里发生的事情,我首先删除代码的速记部分,这可能有助于我的解释。

无法使用NullDBNull分配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。