2014-11-04 16 views
1

情況是這樣的:其中母體具有參照子反之亦然VB.Net克隆層級 - >循環引用

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函數並傳遞參數嗎?

回答

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 
+0

謝謝史蒂文。雖然我以另一種方式解決了這個問題(對象從根本上改變了),但您的解決方案將是一個好方法。 – Recipe 2014-11-05 09:01:40