-
23-08-2019 - |
質問
私にとっては、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
常に戻ります true
, 、参照が新しいクラスに渡されたとしても UsingClass
参照ではなく、「価値によって」。したがって、クラスのコピーは作成されていませんが、ローカル変数は作成されています myReference
の UsingClass
それでもプロパティを参照/指しています Reference
の RuntimeOrSomething
.
これはどのようにエレガントに説明できますか?
解決
参照はオブジェクトのインスタンスを指しますが、オブジェクトのインスタンスではありません。オブジェクトへの指示のコピーを作成しても、別のオブジェクトが作成されるわけではなく、同じオブジェクトを指す別の参照を作成します。
他のヒント
私は今この答えに多くの時間を費やすことはできません - 私の膝に幼児を乗せて電車で入力する - しかし、私は助けになるかもしれないいくつかの記事を持っています。それらはC#について書かれていますが、同じことがVB.NETにも当てはまります:
から MSDN:
byvalキーワードを使用して値で変数引数を渡すと、手順は変数自体を変更できません。 ただし、引数が参照タイプである場合、オブジェクト自体を置き換えることができなくても、ポイントするオブジェクトのメンバーを変更できます。 特に、オブジェクトのメンバーを変更できます。たとえば、引数が配列変数である場合、新しい配列を割り当てることはできませんが、その要素の1つ以上を変更できます。変更された要素は、呼び出しコードの基礎となる配列変数に反映されます。
ReferenceClassはリファレンスタイプであるため、Byvalを渡すと、新しいオブジェクト(そうではありません)に置き換えることはできませんが、その内臓(これを行う)で釣りをすることができます。 BYREFまたはBYVALを通過するかどうかにかかわらず、その内臓をマッキングすることは、元のオブジェクトに「影響」に「影響」します(メモリには1つのオブジェクトしかないため)。
この行で:
Dim tempClass as New UsingClass(Reference)
によって言及されるオブジェクト Reference
プロパティは「価値によって」渡されますが、それは 物体 それはコピーされています、 それはです 参照 コピーされたそのオブジェクトに (つまり、myReferenceとtempclass.Referenceは、同じオブジェクトに2つの異なる「ポインター」です。 tempClass.Reference = new ReferenceClass
そして、myReferenceとtempclass.Referenceはまだ2つの異なる「ポインター」ですが、今ではそれぞれ2つの異なるオブジェクトを指しています。
vb.netでクラスを渡すとき、Cプログラミングとポインターの観点からそれを考えることができます -
ByVal = passing arguments via - a pointer ByRef = passing arguments via - a pointer to a pointer
例として文字列を取ります
' 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
上記のように、オブジェクト変数を別のオブジェクト変数を設定すると、「ポインター」をメモリ内の同じオブジェクトのインスタンスに設定するだけです。
Public Function Clone() As Object Implements ICloneable.Clone
Return Me.MemberwiseClone()
End Function
あなたが割り当てるときとあなたがオブジェクトを割り当てるとき、クローン・メソッドを使用します
Dim tempClass as ReferenceClass = Reference.Clone