2011-02-23 59 views
0

我在這裏看到了很多關於我的問題的文章,但沒有一篇真正回答我所問的內容。我正在創建一個我可以設想的分支對象的類,就像TreeView控件的TreeNode對象一樣。每個分支可以有任何數量的分支孩子在下面(因此在上面)。這裏是我的,而簡單的類:如何創建一個可以有父母和子女關係的類

public class Branch { 
    public string Name { get; set; } 
    public string Link { get; set; } 
    public Branch Parent { get; private set; } 
    public List<Branch> Children { get; set; } 

    internal Branch(string Name, string Link) { 
     this.Name = Name; 
     this.Link = Link; 
     this.Children = new List<Branch>(); 
    } // Branch - Constructor - Overload 

    internal Branch(string Name, string Link, List<Branch> Children) { 
     this.Name = Name; 
     this.Link = Link; 
     this.Children = Children; 

     this.Children.ForEach(delegate(Branch branch) { 
      branch.Parent = this; 
     }); 
    } // Branch - Constructor - Overload 

    public bool HasChildren { 
     get { return this.Children.Count > 0; } 
    } // HasChildren - Property - ReadOnly 

    public string Path { 
     get { 
      string Result = ""; 

      Branch parent = this; 
      while (parent != null) { 
       Result = string.Format("{0}/{1}", parent.Name, Result); 
       parent = parent.Parent; 
      } // while stepping up the tree 

      return string.IsNullOrWhiteSpace(Result) ? "" : Result.Substring(0, Result.Length - 1); 
     } // get 
    } // Path - Property - ReadOnly 

這個偉大的工程,如果我在喜歡實例化時添加的孩子以下幾點:

List<Branch> Branches = new List<Branch>() { 
    new Branch("First", "#"), 
    new Branch("Second", "#"), 
    new Branch("Third", "#", new List<Branch>() { 
     new Branch("ThirdSub1", "#"), 
     new Branch("ThirdSub2", "#") 
    }), 
    new Branch("Fourth", "#"), 
    new Branch("Fifth", "#"), 
    new Branch("Sixth", "#", new List<Branch>() { 
     new Branch("SixthSub1", "#"), 
     new Branch("SixthSub2", "#", new List<Branch>() { 
      new Branch("SixthSub2Sub1", "#"), 
      new Branch("SixthSub2Sub2", "#"), 
      new Branch("SixthSub2Sub3", "#", new List<Branch>() { 
       new Branch("Deep Deep Deep Undercover", "#"), 
      }), 
     }), 
    }), 
    new Branch("Seventh", "#"), 
    new Branch("Eighth", "#"), 
}; 

但是,如果我做到以下幾點:

List<Branch> Branches = new List<Branch>(); 
Branch Test = Branches.Add(new Branch("Something", "")); 
Test.Children.Add(new Branch("Child Here", "")); 

「此處的子節點」節點沒有與之關聯的父節點。因此它被打破,當然Path屬性不起作用。

我想我可以重寫List的Add方法,但這是不允許的。處理這個問題的最好方法是什麼?目前我並沒有像MyBranches那樣創建我自己的集合類,但是如果在實現IList或ISet或Collection時需要做某些工作,那麼我願意這麼做。但請舉個例子。

謝謝!

+0

爲您的分支類型嘗試擴展方法。這是添加重載的一種方法。也就是說,如果你的類型繼承自IList。不幸的是,你無法訪問受保護或私人成員。 – 2011-02-23 16:25:41

回答

4

只是人們在未來尋找這個相同的解決方案,這裏是滿級:

public class Branch { 
    public string Name { get; set; } 
    public string Link { get; set; } 
    public Branch Parent { get; set; } 
    public TreeBranches Children { get; private set; } 

    internal Branch(string Name, string Link) { 
     this.Name = Name; 
     this.Link = Link; 
     this.Children = new TreeBranches(this); 
    } // Branch - Constructor - Overload 

    internal Branch(string Name, string Link, TreeBranches Children) { 
     this.Name = Name; 
     this.Link = Link; 
     this.Children = Children; 

     this.Children.ToList().ForEach(delegate(Branch branch) { 
      branch.Parent = this; 
     }); 
    } // Branch - Constructor - Overload 

    /// <summary> 
    /// Returns a boolean indicating if the given Branch has any child Branches. 
    /// </summary> 
    public bool HasChildren { 
     get { return this.Children.Count > 0; } 
    } // HasChildren - Property - ReadOnly 

    /// <summary> 
    /// Gets the path from the oldest ancestor to the current Branch. 
    /// </summary> 
    public string Path { 
     get { 
      string Result = ""; 

      Branch parent = this; 
      while (parent != null) { 
       Result = string.Format("{0}/{1}", parent.Name, Result); 
       parent = parent.Parent; 
      } // while stepping up the tree 

      return string.IsNullOrWhiteSpace(Result) ? "" : Result.Substring(0, Result.Length - 1); 
     } // get 
    } // Path - Property - ReadOnly 

} // Branch - Class 

public class TreeBranches : IList<Branch> { 
    private List<Branch> branches = new List<Branch>(); 
    private Branch owner; 

    public TreeBranches() { 
     this.owner = null; 
    } 

    public TreeBranches(Branch owner) { 
     this.owner = owner; 
    } 

    public void Add(Branch branch) { 
     branch.Parent = this.owner; 
     this.branches.Add(branch); 
    } 

    #region Standard IList Method Implementation 

    IEnumerator<Branch> IEnumerable<Branch>.GetEnumerator() { return this.branches.GetEnumerator(); } 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.branches.GetEnumerator(); } 
    public int IndexOf(Branch item) { return this.branches.IndexOf(item); } 
    public void Insert(int index, Branch item) { this.branches.Insert(index, item); } 
    public void RemoveAt(int index) { this.branches.RemoveAt(index); } 
    public Branch this[int index] { 
     get { return this.branches[index]; } 
     set { this.branches[index] = value; } 
    } 

    public void Clear() { this.branches.Clear(); } 
    public bool Contains(Branch item) { return this.branches.Contains(item); } 
    public void CopyTo(Branch[] array, int arrayIndex) { this.branches.CopyTo(array, arrayIndex); } 
    public int Count { get { return this.branches.Count(); } } 
    public bool IsReadOnly { get { return this.IsReadOnly; } } 
    public bool Remove(Branch item) { return this.branches.Remove(item); } 

    #endregion Standard IList Method Implementation 
} // TreeBranches - Class 
+0

已經照顧好了。謝謝里德! – Grandizer 2011-02-23 18:00:04

+0

雖然第二,這並沒有真正回答這個問題。這隻有1層深。如果我將一個子項(分支)添加到其中一個子分支對象,則其父項未設置,因爲此時它正在使用無法覆蓋的內部列表的添加方法。 – Grandizer 2011-02-23 18:39:37

+0

@Grandizer:它應該 - 而不是使用列表,你使用Branch中的MyBranches。通過這種方式,添加元素始終設置父級,無論級別如何發生...... – 2011-02-23 18:47:44

0

您可以從Collection<T>而不是List<T>派生,List<T>速度更快,而且對性能進行了優化,但Collection<T>更具擴展性,並允許您覆蓋Add()等。

如果性能不是問題,那麼使用Collection<T>,如果性能是一個問題,而不是使用Reed的示例在您的類中包含List<T>