2016-12-15 38 views
0

我使用Nullable(Of Integer)和剛剛被蜇Nothing正在施放到0,這是excatly使用Nullable(Of Integer)時,我不想要什麼。奇的互動「如果」和可空(整數)

func1下面的行爲不像我預期的那樣。我可以通過修改它來實現我的意願(請參閱func2)。但我不明白爲什麼這是必要的(我想我可能會覺得很難記住這麼做)。

爲什麼不是func1做我想要的?我想我以前遇到過這種情況,我寧願不再看到它。

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 

我得到(在LINQPad運行此)的結果是:在你的情況

True 
True 

True 
False 

回答

2

事實很重要:

  • 在線If方法預計雙方 「真」 和「假「表達式 必須返回相同的類型。
  • Nothing是類型的默認值。
    對於Integer它是0
    作爲參考類型是null

在第一種方法中的內聯If方法預計,「假」的表達必須返回一個Integer,因爲基於Nothing編譯器不能決定返回類型,它將使用「真」生產型表達。因此Nothing將產生默認值Integer類型,即0

在第二種方法中這兩個參數都顯式聲明返回類型,其中Integer可以隱式轉換到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

爲了解釋這裏發生了什麼,我會刪除你的代碼的簡寫部分可能與我的解釋幫助啓動。

無法使用NullDBNull分配VB.net中的整數。您可以使用Nullable-of-T來指定IT。但是,只要您創建對象Nullable-ish,就可以評估爲0。

考慮以下

dim x as Integer = nothing 'evaluates to x=0 

所以,當你的函數運行,您使用DirectCast()返回一個可空十歲上下的整數,然後計算是不可空的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 
+0

我會修改我的答案。 –

+0

Brainmelt。謝謝@法比奧。我已經在我的回答中說明了:) –

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 

的操作者如果,如果(FOO,富=真,富=假),應謹慎使用,因爲它是比標準如果構建慢。

編輯:關於If運算符的聲明不正確。

感謝克里斯。

+1

你有這方面的資料嗎?我做了一個簡單的基準測試,運行了大約1000000次代碼迭代,丟棄了前1000個左右。結果:'如果操作符':0.0000116 ms,'If Then Else':0.0000093 ms。所以雖然'If'運算符稍微慢一些,但它似乎並不重要。基準測試代碼使用秒錶進行計時。 –

+1

我上面的評論中的時間不包括使用Nullable(Of Integer)或'DirectCast'。當我將測試中的代碼更改爲包含該代碼時,時間增加了,但與第一個測試一致:'If':0.0000345'If Else' 0.0000333。我猜測時間的增加是由於'DirectCast'造成的。 –

+0

@ChrisDunaway - 我可能一直在想着IIf。 – dbasnett