【问题标题】:VB.Net clone hierarchy where parent has reference to child and vice versa -> circular referenceVB.Net 克隆层次结构,其中父级引用子级,反之亦然 -> 循环引用
【发布时间】:2014-11-04 11:16:21
【问题描述】:

情况是这样的:

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

【问题讨论】:

    标签: vb.net design-patterns circular-reference icloneable


    【解决方案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
    

    【讨论】:

    • 谢谢史蒂文。虽然我确实以另一种方式解决了这个问题(对象从根本上改变了),但您的解决方案将是一个好方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    相关资源
    最近更新 更多