2016-12-15 5 views
0

私はNullable(Of Integer)を使用していて、ちょうどNothingが0にキャストされています。Nullable(Of Integer)を使用しているときに嫌なことがあります。"If"と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 

結果は以下のとおりです。あなたのケースで重要な

True 
True 

True 
False 

答えて

2

事実:両方の "真" と「偽ことが期待

  • インラインIf方法式 は同じタイプを返す必要があります。
  • Nothingはtypeのデフォルト値です。
    Integerについては0です。参照型の場合
    それはIf方法は、コンパイラがNothingに基づいて戻り値の型を決めることができないので、それが「真」で生成タイプを使用しますが、「偽」という表現はIntegerを返さなければならないことを期待する第一の方法をインラインでnull

です表現。したがって、NothingIntegerタイプのデフォルト値0を生成します。

両方のパラメータで明示的に返された型が宣言されています。Integerを暗黙的にNullableに変換できるため、コンパイラはIfメソッドの結果としてNullableを返します。

問題の重要な役割は、インラインIfメソッドです。これはIntegerのデフォルト値としてNothingを使用します。

あなたは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

せずに動作しますが、私は私の説明を助けるかもしれない、あなたのコードの速記一部を除去することから始めましょう。

NullまたはDBNullを使用してVB.netの整数を割り当てることはできません。あなたはそのままNullable-of-Tを使ってITを割り当てることができます。ただし、オブジェクトNullable-ishを作成するとすぐに、0と評価されます。

は、だからあなたの関数が実行されるとき、あなたはその後、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

によってNULL可能ではないことが評価され、NULL可能っぽい整数を返すようにDirectCast()を使用ここで関数func1は、以下の

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

を考えてみましょう書き直す。鋳造の必要はないことに注意してください。

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、FOO =真、FOO = false)の場合は、慎重に使用しなければなりません。

編集: If演算子に関する記述が正しくありません。

Chrisさんに感謝します。

+1

それのためのソースがありますか?私は最初の1000程度を捨てて、コードの約100000000反復を走らせる簡単なベンチマークを作った。結果: 'If operator':0.0000116ms、If Then Else':0.0000093ms。したがって、 'If'演算子は若干遅くなりましたが、それはまったく重要ではないようです。ベンチマークコードは、そのタイミングのためにストップウォッチを使用しました。 –

+1

私の上記コメントのタイミングにNullable(Of Integer)や 'DirectCast'の使用は含まれていませんでした。テスト中のコードを変更すると、そのタイミングも増加しましたが、最初のテストと一貫していました。If If:0.0000345 If If Else 0.0000333。私は時間の増加が 'DirectCast'によると推測します。 –

+0

@ChrisDunaway - 私はIIfを考えていたかもしれません。 – dbasnett

関連する問題