1

This is the situation:

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

The actual object is more complex, having several levels. I'm not sure how to solve this because, at the moment, whenever you call Clone on the parent A class, you will end up with a circular reference.

How can I avoid this situation? Should I create my own Clone function and pass along a parameter?

4

1 回答 1

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
于 2014-11-04T13:15:11.793 回答