简体   繁体   English

如何创建可以建立父子关系的课程

[英]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. 我正在创建我的Branch对象的类,您可以像TreeView控件的TreeNode对象一样进行设想。 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 - 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. 因此,它已损坏,并且Path属性当然不起作用。

I thought I could override the List's Add method but that is not allowed. 我以为我可以覆盖List的Add方法,但这是不允许的。 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. 目前,我并没有创建自己喜欢的MyBranches这样的Collection类,但是如果在实现IList或ISet或Collection时可以做某种需要的事情,那么我愿意这样做。 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. 您可以从Collection<T>而不是List<T>派生出来, List<T>更快,并且针对性能进行了优化,但是Collection<T>更具扩展性,可以覆盖Add()和其他。

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. 如果性能不成问题,则使用Collection<T> ,如果性能成问题,则不使用Reed在您自己的类中包含List<T>的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM