自动设置子项的父引用

时间:2010-02-09 15:17:41

标签: c#

我有一个包含名为IList<T>的{​​{1}}属性的类。每个孩子都应该参考其父母。我的解决方案是在Children getter中设置ChildClass.Parent属性。有没有更好的方法,或者这是最好的解决方案?

ParentClass.Children

2 个答案:

答案 0 :(得分:8)

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

如果是真正的父母 - &gt;孩子的关系,你不应该允许任何人创建一个孤儿。因此,应在创建时将Child设置为Child。

我可能会这样做:

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

答案 1 :(得分:0)

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

我建议如下:

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

除非集合是不可变的,否则不要返回对内部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(); }
    }
}