How to Create a Class That Can Have Parent and Child Relationship
I have seen quite a few articles on here about my question but none really answer what I am asking. I am creating a class of my Branch objects that you can envision as just like the TreeNode objects of the TreeView control. Each Branch can have any number of Branch children below (and therefore above) it. Here is my rather simple class:
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 -开发者_C百科 Property - ReadOnly
This works GREAT if I Add children at the time of instantiation like the following:
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", "#"),
};
But if I do the following:
List<Branch> Branches = new List<Branch>();
Branch Test = Branches.Add(new Branch("Something", ""));
Test.Children.Add(new Branch("Child Here", ""));
The "Child Here" node does NOT have a Parent associated with it. Thus it is broken and of course the Path property doesn't work property.
I thought I could override the List's Add method but that is not allowed. What is the best way to handle this? Currently I am not creating my own Collection Class like MyBranches, which I like, but if there is a way of doing what I need while implementing IList or ISet or Collection, then I am willing to do so. But please provide an example.
Thanks!
Just for people in the future looking for this same solution, here is the full class:
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
You can derive from Collection<T>
instead of List<T>
, List<T>
is faster, and is optimized for performance, but Collection<T>
is more extensible and allows you to override Add()
and others.
If performance is not an issue, then use Collection<T>
, and if performance is an issue than use Reed's example of containing a List<T>
in your own class.
精彩评论