6

VB.NET で Nothing を返す構造体と関数を使用すると頭が痛くなります。

このコードでここで説明してみましょう:

Public Class Form1
    Structure Test
        Dim field1 As String
    End Structure

    Private Function Foo() As Test
        Return Nothing
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim st As Test = Foo()
    End Sub
End Class

前のコードで、 Foo 関数の結果として Nothing を返す場合、stNothingであることが期待されます。しかし、これは起こりません。

次に、MSDNのドキュメントで見つけました:

変数に Nothing を代入すると、宣言された型の既定値に設定されます。その型に変数メンバーが含まれている場合、それらはすべて既定値に設定されます。

そのため、構造体にNothingを割り当てると、構造体自体ではなく、そのすべてのメンバーがデフォルト値に設定されることがわかりました。

また、次のように宣言してstを Nullable 型 にしようとしました。

    Dim st As Nullable(Of Test) = Foo()  

しかし、それでもstが Nothing であるかどうかを確認することはできません:

    If st Is Nothing Then  

また

    If st.Equals(Nothing) Then

では、質問: 1 - Nothingをメンバーではなく、構造体
に割り当てることは可能ですか? 2 - 構造体の戻り値がNothingかどうかを確認するにはどうすればよいですか?

4

3 に答える 3

19

構造体は値型であり、Nothing にすることはできません。Nullable 型は問題を解決できます。型名の後に疑問符を付けて、短くて機敏にします。次に例を示します。

Module Module1

    Structure Test
        Dim field1 As String
    End Structure

    Private Function Foo() As Test?
        Return Nothing
    End Function

    Sub Main()
        Dim st As Test? = Foo()
        Debug.Assert(st is Nothing)
    End Sub

End Module
于 2010-07-02T21:00:27.563 に答える
13

次の最初の 2 つのメソッドは、.NET Framework で頻繁に使用されます。使用する方法は、要件によって異なります。構造のテスト頻度が低い場合は、方法 3 を使用します。頻繁なテストでは、方法 #2 が「空の」テストに適していない場合は、方法 #1 を使用します。たとえば、このPoint構造では空のポイントを {x=0,y=0} と定義していますが、これは正しくないと思います。したがって、ポイント構造の実装では最初の方法を使用します。

Empty方法 1:比較テスト用のテストを定義する

Test空比較に使用するshared を追加します。

Structure Test
    Public Shared Empty As Test = New Test
    Dim field1 As String 
End Structure 

次のようにテストします。

If st = Test.Empty Then

IsEmpty方法 2:テスト用のプロパティを定義する

IsEmpty構造の内部状態に基づいてプロパティを定義します。

Structure Test 
    Public ReadOnly Property IsEmpty As Boolean
        Get
            Return Len(field1) = 0
        End Get
    End Property
    Dim field1 As String 
End Structure 

次のようにテストします。

If st.IsEmpty Then

方法 3: Nullable(Of T) を使用する

次のように定義します。

Dim st As Test? = Foo() 
'--or--
Dim st As Nullable(Of Test) = Foo()

次のようにテストします。

If st Is Nothing Then
'--or--
If st.HasValue = False Then

ノート

上記のコードをテストしておらず、コード ライブラリにアクセスできません。

インスピレーション

公開されているソース コードまたは.NET Reflectorを使用して、Microsoft の構造を調べてPointください。Color

于 2010-07-02T21:04:18.897 に答える
0

「構造体には何も割り当てず、メンバーには割り当てない」という概念はありません。

null 許容値型を検討Nullable(Of T)する必要があるように思えます。値型の「実際の」値が存在しないことを表現できる必要がある場合は、まさにそれが発明された理由です。

Byteたとえば、考えてみましょう。値には、256 個のByte値 (0 ~ 255) のいずれかを指定できます。value を割り当てると、実際には 0 になります。byte として格納されるため、Nothing「0 ~ 255 の範囲にない値」にすることはできません。実際、VBがここで使用できるようにしたことは、やや残念なことだと思います... 哲学的には、「欠落」値と値 0 は実際には非常に異なるものだからです。Nothing

とにかく、null 許容値型は「通常の」値型をラップし、本当に有用な値が存在するかどうかを示す追加のブール値を提供します。

于 2010-07-02T20:51:45.263 に答える