首先,我知道类似的问题: 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 ?
我不希望在这里用勺子喂食这种解决方案并继续前进;我很感激解释" ="运算符实际上是在内部运行并决定它将如何执行赋值(以及我如何影响它)。欢迎推广到其他语言。
修改
似乎有些混乱。我意识到重载" ="是不可能/不可取的。运营商。我想了解操作员的工作原理。然后我可以自己确定如何通过键入赋值语句来执行深层复制。
例如,这可能是也可能不是运营商行为的正确完全描述性定义:
我正在寻找上述明确的行为概述。
答案 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()>
属性。