繁体   English   中英

自动在子项上设置父引用

[英]Automatically set parent reference on child items

我有一个包含IList<T>属性(称为Children 每个孩子都应参考其父母。 我的解决方案是在ParentClass.Children getter中设置ChildClass.Parent属性。 有没有更好的方法,还是最好的解决方案?

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;
        }
    }
}

可能只是我...但是这看起来像是一个糟糕的设计。

如果这是真正的“父母->子女”关系,则不应允许任何人创建“孤儿”。 因此,在创建时应将父级设置在子级上。

我可能会做类似的事情:

class ChildClass
{
    private ParentClass _parent;

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

然后:

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;
    }
}

解决方案的问题是,如果所有子代和父代都正确链接,则每次检索内部子代集时,您的代码都会重新链接它们。 另外,似乎还存在此问题,因为您将返回对私有集合的引用,此后您将无法控制其中包含的元素。

我建议以下内容:

ParentClass上提供Add(ChildCLass)Remove(ChildClass)方法,并在那里强制执行父子约束。 这样,可以在任何位置创建子级,并在属于层次结构时正确地链接它们。 从层次结构中删除时,将不再链接。

除非该集合是不可变的,否则不要返回对您内部ChildClass集合的引用。 最好返回ReadOnlyCollectionIEnumerable

例子:

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