简体   繁体   English

自动在子项上设置父引用

[英]Automatically set parent reference on child items

I have a class that contains an IList<T> property called Children . 我有一个包含IList<T>属性(称为Children Each child should reference its parent. 每个孩子都应参考其父母。 My solution has been to set the ChildClass.Parent property in the ParentClass.Children getter. 我的解决方案是在ParentClass.Children getter中设置ChildClass.Parent属性。 Is there a better way, or is this the best solution? 有没有更好的方法,还是最好的解决方案?

class ParentClass
{
    private IList<ChildClass> _children;

    public virtual IList<ChildClass> Children
    {
        get
        {
            // make sure each child refers to its parent (this)
            foreach (ChildClass c in _children)
            {
                c.Parent = c.Parent ?? this;
            }
            return _children;
        }
        set
        {
            _children = value;
        }
    }
}

It could just be me...but this looks like a bad design. 可能只是我...但是这看起来像是一个糟糕的设计。

If it's a true Parent -> Child relationship, you shouldn't allow anybody to create an Orphan Child. 如果这是真正的“父母->子女”关系,则不应允许任何人创建“孤儿”。 Therefore, the Parent should be set on the Child at the time of creation. 因此,在创建时应将父级设置在子级上。

I would probably do something like: 我可能会做类似的事情:

class ChildClass
{
    private ParentClass _parent;

    public ChildClass(ParentClass parent)
    {
        _parent = parent;
    }
}

And then: 然后:

class ParentClass
{
    private List<ChildClass> _children;

    public virtual ReadOnlyCollection<ChildClass> Children
    {
        get
        {
            return _children.AsReadOnly();
        }
    }

    public virtual ChildClass CreateChild()
    {
        // Set parent in child class constructor
        ChildClass newChild = new ChildClass(this);

        _children.Add(newChild);

        return newChild;
    }
}

The problem with your solution is that if all the children and parents are correctly linked, your code will re-link them each time the internal child collection is retrieved. 解决方案的问题是,如果所有子代和父代都正确链接,则每次检索内部子代集时,您的代码都会重新链接它们。 Also, it seems that this problem exists because you are returning a reference to a private collection, after which you lose control of the elements it contains. 另外,似乎还存在此问题,因为您将返回对私有集合的引用,此后您将无法控制其中包含的元素。

I suggest the following: 我建议以下内容:

Provide Add(ChildCLass) and Remove(ChildClass) methods on ParentClass , and enforce the parent-child constraint there. ParentClass上提供Add(ChildCLass)Remove(ChildClass)方法,并在那里强制执行父子约束。 This allows children to be created anywhere, and be linked correctly when belonging to the hierarchy. 这样,可以在任何位置创建子级,并在属于层次结构时正确地链接它们。 When the are removed from the hierarchy, the are no longer linked. 从层次结构中删除时,将不再链接。

Do not return a reference to your internal ChildClass collection unless the collection is immutable. 除非该集合是不可变的,否则不要返回对您内部ChildClass集合的引用。 Returning a ReadOnlyCollection or IEnumerable is preferable. 最好返回ReadOnlyCollectionIEnumerable

Examples: 例子:

class ChildClass
{
    // Prevent unauthorized clients from overriding the Parent reference.
    public ParentClass Parent { get; internal set; }

    // ... other methods and properties ...
}

class ParentClass
{
    private IList<ChildClass> _children;

    public void AddChild(ChildClass child)
    {
        _children.Add(child);
        child.Parent = this;
    }

    public RemoveChild(ChildClass child)
    {
        _children.Remove(child);
        child.Parent = null;
    }

    public IList<ChildClass> Children
    {
        get { return _children.AsReadOnly(); }
    }
}

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

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