情况如下:
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
函数并传递参数吗?
最简单的解决方案是让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