Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.Net克隆层次结构,其中父级引用子级,反之亦然->;循环引用_Vb.net_Design Patterns_Circular Reference_Icloneable - Fatal编程技术网

VB.Net克隆层次结构,其中父级引用子级,反之亦然->;循环引用

VB.Net克隆层次结构,其中父级引用子级,反之亦然->;循环引用,vb.net,design-patterns,circular-reference,icloneable,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

情况就是这样:

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

最简单的解决方案是让
子类不克隆
父属性。当
子项
克隆自身时,它可以使
父项
属性保持不变,也可以将其保留为空。例如:

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

谢谢你,史蒂文。虽然我用另一种方法解决了这个问题(对象发生了根本性的变化),但您的解决方案将是一个很好的方法。