情况就是这样:
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
实际对象更复杂,有几个级别。
我不确定如何解决这个问题,因为目前,只要您在父Clone
课程上致电A
,您就会得到一个循环引用。
我该如何避免这种情况?我应该创建自己的Clone
函数并传递参数吗?
答案 0 :(得分:1)
最简单的解决方案是让Child
类完全不克隆Parent
属性。当Child
克隆自身时,它可以使Parent
属性保持不变,或者将其保留为空。例如:
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