VB.Net克隆层次结构,其中父级引用子级,反之亦然->;循环引用
情况就是这样:VB.Net克隆层次结构,其中父级引用子级,反之亦然->;循环引用,vb.net,design-patterns,circular-reference,icloneable,Vb.net,Design Patterns,Circular Reference,Icloneable,情况就是这样: Class A Implements ICloneable Public Property Children As List(Of Child) Public Function Clone() As Object Implements ICloneable.Clone Return New A With { .Children = Children.Select(Function(c) DirectCast(c
Class A
Implements ICloneable
Public Property Children As List(Of Child)
Public Function Clone() As Object Implements ICloneable.Clone
Return New A With {
.Children = Children.Select(Function(c) DirectCast(c.Clone(), Child)).ToList()
}
End Function
End Class
Class Child
Implements ICloneable
Public Property Parent As A
Public Function Clone() As Object Implements ICloneable.Clone
Return New Child With {
.Parent = DirectCast(Parent.Clone(), A)
}
End Function
End Class
实际对象更复杂,具有多个级别。
我不知道如何解决这个问题,因为目前,无论何时在父类A
上调用Clone
,最终都会得到一个循环引用
我怎样才能避免这种情况?我是否应该创建自己的
Clone
函数并传递一个参数?最简单的解决方案是让子类不克隆父属性。当子项
克隆自身时,它可以使父项
属性保持不变,也可以将其保留为空。例如:
Class Child
Implements ICloneable
Public Property Parent as A
Public Function Clone() As Object Implements ICloneable.Clone
Return New Child() With { .Parent = Me.Parent }
End Function
End Class
然后,当父级A
类克隆自身时,它可以设置所有克隆子级的parent
属性,如下所示:
Class A
Implements ICloneable
Public Property Children As List(Of Child)
Public Function Clone() As Object Implements ICloneable.Clone
Return New A() With
{
.Children = Me.Children.Select(
Function(c)
Dim result As Child = DirectCast(c.Clone(), Child))
result.Parent = Me
Return result
End Function).ToList()
}
End Function
End Class
或者,正如您所建议的,您可以创建自己的Clone
方法,该方法将父对象作为参数:
Class Child
Public Property Parent as A
Public Function Clone(parent As A) As Object
Return New Child() With { .Parent = parent }
End Function
End Class
它不会实现ICloneable
,但只要您不需要它与其他类型的ICloneable
对象互换,那么这就无关紧要了。类似地,您可以重载构造函数:
Class Child
Public Property Parent as A
Public Sub New()
End Sub
Public Sub New(childToClone As Child, parent As A)
' Copy other properties from given child to clone
Me.Parent = parent
End Sub
End Class
谢谢你,史蒂文。虽然我用另一种方法解决了这个问题(对象发生了根本性的变化),但您的解决方案将是一个很好的方法。