3

VB.NET のクラスへの参照 (ポインタ?) は、私にはやや不明確です。私が尋ねようとしている質問は、少しテストすることで答えることができますが、誰かが適切な説明 (またはリンクも) を投稿できるかどうか疑問に思っていました。

クラスを作成する場合:

Public Class ReferenceClass

    Private myBooleanValue As Boolean = False
    Public Property BooleanValue As Boolean
        Get
            Return myBooleanValue
        End Get
        Set(value As Boolean)
            myBooleanValue = value
        End Set
    End Property

End Class

そして、実際にこのクラスをプロパティとして使用するクラス:

Public Class UsingClass

     Private myReference As ReferenceClass
     Public Property Reference As ReferenceClass
        Get
             return myReference
         End Get
         Set(value As ReferenceClass)
             myReference = value
         End Set
     End Property

     Public Sub New(ByVal Reference As ReferenceClass)
         myReference = Reference
     End Sub

End Class

そして、次のように使用します。

Public Class RuntimeOrSomething

     Public Shared myReference As ReferenceClass
     Public Shared ReadOnly Property Reference As ReferenceClass
         Get
             If myReference Is Nothing Then myReference = new ReferenceClass()
             return myReference
         End Get
     End Property

     Public Shared Function BooleanCheck() As Boolean
         Reference.BooleanValue = True
         Dim tempClass As New UsingClass(Reference)
         tempClass.Reference.BooleanValue = False

         Return (tempClass.Reference.BooleanValue = Reference.BooleanValue)
     End Sub

     Public Shared Sub DoNothing()
          Reference.BooleanValue = True
          Dim someBoolean As Boolean = BooleanCheck

          ' Now Reference.Booleanvalue is "False"
     End Sub

End Class

これで、参照が参照ではなく「値によって」新しいクラスに渡されたとしても、関数BooleanCheckは常に を返します。そのため、クラスのコピーは作成されませんが、 のローカル変数は引き続き のプロパティを参照/ポイントします。trueUsingClassmyReferenceUsingClassReferenceRuntimeOrSomething

これはどのようにエレガントに説明できますか?

4

6 に答える 6

8

参照はオブジェクトのインスタンスを指しますが、オブジェクトのインスタンスではありません。オブジェクトへの方向のコピーを作成しても、別のオブジェクトは作成されません。同じオブジェクトを指す別の参照が作成されます。

于 2008-12-23T17:32:44.047 に答える
7

私は今、この答えに多くの時間をかけることができません-私の膝に幼児を乗せて電車でタイプする-しかし、私は役立つかもしれないいくつかの記事を持っています。それらはC#について書かれていますが、同じことがVB.NETにも当てはまります。

于 2008-12-23T17:25:49.570 に答える
2

MSDNから:

ByVal キーワードを使用して変数の引数を値で渡す場合、プロシージャは変数自体を変更できません。ただし、引数が参照型の場合、オブジェクト自体を置き換えることはできませんが、引数が指すオブジェクトのメンバーを変更できます。特に、オブジェクトのメンバーを変更できます。たとえば、引数が配列変数の場合、新しい配列を割り当てることはできませんが、その要素の 1 つまたは複数を変更することはできます。変更された要素は、呼び出し元のコードの基になる配列変数に反映されます。

ReferenceClass は参照型であるため、ByVal を渡すと、それを新しいオブジェクトに置き換えることはできませんが (そうしないでください)、その内部をいじることはできます (そうします)。ByRef を渡すか ByVal を渡すかに関係なく、その内部をいじると元のオブジェクトに "影響" を与えます (メモリにはオブジェクトが 1 つしかないため)。

于 2008-12-23T20:08:08.993 に答える
1

この行で:

Dim tempClass as New UsingClass(Reference)

プロパティによって参照されるオブジェクトReferenceは「値によって」渡されますが、コピーされるのはオブジェクトではなく、コピーされるのはそのオブジェクトへ参照です(つまり、myReference と tempClass.Reference は同じオブジェクトへの 2 つの異なる「ポインター」です。その後tempClass.Reference = new ReferenceClass、myReference と tempClass.Reference は依然として 2 つの異なる「ポインター」ですが、それぞれが 2 つの異なるオブジェクトを指しています。

于 2008-12-23T18:44:35.667 に答える
1

VB.NET でクラス byval/byref を渡す場合、C プログラミングとポインターの観点から次のように考えることができます。

ByVal = 経由で引数を渡す - ポインター
ByRef = 経由で引数を渡す - ポインタへのポインタ

文字列を例にとる

' ByRef - modify str pointer to "point" to a new string
Sub Test_Ref(ByRef str as string)
    str = "New String ByRef"
End Sub

' ByVal - can't modify str pointer must return a (pointer to) new string
Function Test_Val(ByVal str as String) as String
    Return "New String ByVal"
End Sub

Sub Main()
    Dim strTest as String = "Hello World!"
    Console.WriteLine(strTest)
    Test_Ref(strTest)
    Console.WriteLine(strTest)
    Test_Val(strTest)
    Console.WriteLine(strTest) ' oops still pointing to same string
    strTest = Test_Val(strTest)
    Console.WriteLine(strTest) ' that's better :)
End Sub
于 2008-12-23T19:20:49.430 に答える
0

上記のように、オブジェクト変数を別の変数と等しく設定すると、メモリ内の同じオブジェクトのインスタンスに「ポインタ」が設定されます。オブジェクトのクローンを作成する場合は、次のようなiCloneableインターフェイスの実装を検討してください。

Public Function Clone() As Object Implements ICloneable.Clone
Return Me.MemberwiseClone()
End Function

オブジェクトを割り当てるときは、cloneメソッドを使用します

Dim tempClass as ReferenceClass = Reference.Clone
于 2008-12-28T08:46:30.720 に答える