VB.NET中的赋值运算符“=”

时间:2014-08-04 07:38:50

标签: .net vb.net assignment-operator

首先,我知道类似的问题: Assignment "=" operator in VB.NET 1.1

假设我有一个包含 ArrayList 的VB.NET 结构

 Structure MarbleCollection
    Private marbles As ArrayList
 End Structure

 Class Marble
    Public name As String
    Public radius As Double
 End Class

我想了解当我创建两个 MarbleCollection 实例并使用" = "将一个实例分配给另一个实例时会发生什么?操作者:

 marbleCol1 = marbleCol2

根据上述相关问题的接受答案:

  

如果类型是引用类型(即:类),它是引用副本。如果它是值类型(结构),它将按成员副本执行成员。

当会员逐个复制'执行(当分配值类型时),VB.NET真的只是递归地调用每个成员上的赋值运算符吗?如果是这样,那么在此处将一个 MarbleCollection 分配给另一个 MarbleCollection 将不会产生深层副本,因为两个大理石 ArrayLists 之间的赋值运算符将生成一个引用副本。我想要一份深刻的副本。

有没有办法可以隐式地将引用类型的对象复制为值类型的?例如,我发现扩展 ArrayList 类的功能很有用,但我不希望我的子类通过引用复制其 ArrayList 值,但是而是价值。

举个具体的例子:

 Class BookList
    Inherits ArrayList
 End Class

我可以对 BookList 类(即实现一个接口)做些什么来实现:

 books1 = books2

复制 books2 中的值,并将复制者引用分配给 books1

我不希望在这里用勺子喂食这种解决方案并继续前进;我很感激解释" ="运算符实际上是在内部运行并决定它将如何执行赋值(以及我如何影响它)。欢迎推广到其他语言。

修改

似乎有些混乱。我意识到重载" ="是不可能/不可取的。运营商。我想了解操作员的工作原理。然后我可以自己确定如何通过键入赋值语句来执行深层复制。

例如,这可能是也可能不是运营商行为的正确完全描述性定义:

  1. class1 = class2 - 将 class2 的引用复制到 class1 。他们是同一个实例。
  2. struct1 = struct2 - 为 struct2 中的每个成员执行 struct1.member = struct2.member 。< / LI>
  3. primitive1 = primitive2 - 创建一个新原语,复制 primitive2 的值并将相同的值写入新原语,并提供 primitive1 这个新创建的原语的引用。
  4. 我正在寻找上述明确的行为概述。

1 个答案:

答案 0 :(得分:2)

首先 - 你不能覆盖赋值运算符=(Why aren't assignment operators overloadable in VB.NET?)。 如果将结构分配给新结构,则只复制值字段,引用字段将保持不变(因此新的MarbleCollection.marbles将指向与原始MarbleCollection.marbles相同的对象)。你可以做的是实现你自己的方法,并调用该方法代替深度克隆。

Structure MarbleCollection
    Private marbles As ArrayList
    Public Function Clone() As MarbleCollection
        Dim result = New MarbleCollection()
        If marbles IsNot Nothing Then
            For Each m As Marble In marbles
                result.marbles.Add(m.Clone())
            Next
        End If
        Return result
    End Function
End Structure

Class Marble
    Public name As String
    Public radius As Double
    Public Function Clone() As Marble
        Return DirectCast(Me.MemberwiseClone(), Marble)
    End Function
End Class

如果您正在寻找深度克隆的自动化,我通常会执行二进制序列化,然后进行反序列化(这会给您深度克隆);还有图书馆。

兴趣点 - ICloneable界面。

修改

对于通过序列化进行自动克隆,您可以像这样编写类:

(从Deep cloning objects无耻地重拍)

Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

''' <summary>
''' Reference Article http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
''' Provides a method for performing a deep copy of an object.
''' Binary Serialization is used to perform the copy.
''' </summary>
Public NotInheritable Class ObjectCopier
    Private Sub New()
    End Sub
    ''' <summary>
    ''' Perform a deep Copy of the object.
    ''' </summary>
    ''' <typeparam name="T">The type of object being copied.</typeparam>
    ''' <param name="source">The object instance to copy.</param>
    ''' <returns>The copied object.</returns>
    Public Shared Function Clone(Of T)(source As T) As T
        If Not GetType(T).IsSerializable Then
            Throw New ArgumentException("The type must be serializable.", "source")
        End If

        ' Don't serialize a null object, simply return the default for that object
        If [Object].ReferenceEquals(source, Nothing) Then
            Return Nothing
        End If

        Dim formatter As IFormatter = New BinaryFormatter()
        Dim stream As Stream = New MemoryStream()
        Using stream
            formatter.Serialize(stream, source)
            stream.Seek(0, SeekOrigin.Begin)
            Return DirectCast(formatter.Deserialize(stream), T)
        End Using
    End Function
End Class

下行:MemberwiseClone()和所有&#34;深度克隆&#34;有点慢对象必须标有<Serializable()>属性。