父级引用子级的VB.Net克隆层次结构,反之亦然 - >循环参考

时间:2014-11-04 11:16:22

标签: 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.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函数并传递参数吗?

1 个答案:

答案 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