对我来说,有些不清楚的是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 “按价值”,而不是参考。因此,没有制作课程的副本,而是本地变量 myReferenceUsingClass 仍然引用该属性的参考/点 ReferenceRuntimeOrSomething.

怎么能优雅地解释?

有帮助吗?

解决方案

引用指向对象的实例,它不是对象的实例。将方向的副本放到对象不会创建另一个对象,而是创建另一个指向同一对象的引用。

其他提示

我现在不能花太多时间进入这个答案 - 在膝盖上带有蹒跚学步的火车上打字 - 但是我有几篇文章可能会有所帮助。它们写了有关C#的文章,但也适用于VB.NET:

MSDN:

如果使用Byval关键字通过值传递变量参数,则该过程将无法修改变量本身。 但是,如果参数是参考类型,则可以修改指向对象的成员,即使您无法替换对象本身。 特别是,您可以修改对象的成员。例如,如果该参数是数组变量,则不能为其分配一个新数组,但是您可以更改其一个或多个元素。更改的元素反映在调用代码的基础数组变量中。

由于您的ReferenceClass是一种参考类型,因此,如果您将其传递到Byval,则不能用新对象(您不使用)替换它,但是您可以用它的内在(您这样做)来陷入困境。无论您是通过byref还是Byval,用它的内在陷入困境仍会“影响”原始对象(因为内存中只有一个对象)。

在这一行中:

Dim tempClass as New UsingClass(Reference)

Reference 财产是“按价值”传递的,但不是 目的 被复制, 是的 参考 对被复制的对象 (即myReference and tempClass.Reference是同一对象的两个不同的“指针”。然后您可以做 tempClass.Reference = new ReferenceClass 然后myReference和tempclass.Reference仍然是两个不同的“指针”,但现在它们每个都指向两个不同的对象。

When passing classes byval/byref in VB.NET it is possible to think of it in terms of C programming and pointers such that -

ByVal = passing arguments via - a pointer 
ByRef = passing arguments via - a pointer to a pointer

Take strings as an example

' 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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top