编写封装 parent/child 数据结构的更简单方法?

Easier way to write encapsulated parent/child data structure?

时不时发现自己经常写一个"parents"和"children"的数据结构,其中:

在实现这样的事情之前可能采取的心理步骤可能从这样的事情开始:

public class Parent
{
    private readonly List<Child> _children = new List<Child>();

    public readonly ReadOnlyCollection<Child> Children = _children.AsReadOnly();
}

public class Child
{
    private Parent _parent;

    public Parent Parent
    {
        get
        {
            return _parent;
        }
        set
        {
            if(value == _parent)
                return;

            if(_parent != null)
            {
                _parent._children.Remove(this);
                _parent = null;
            }

            if(value != null)
            {
                value._children.Add(this);
                _parent = value;
            }
        }
    }
}

当然,这不会编译,因为 Parent._childrenprivate。但是,您不想将其设为私有,因为允许 ChildParent 之外的访问可能会违反实施或其他地方的规则。

所以,我想到的一个解决方案是将 Child 嵌套在 Parent 中。嵌套的 classes 可以访问嵌套在 class 中的私有成员:

public class Parent
{
    private readonly List<Child> _children = new List<Child>();

    public readonly ReadOnlyCollection<Child> Children = _children.AsReadOnly();

    public class Child
    {
        private Parent _parent;

        public Parent Parent
        {
            get
            {
                return _parent;
            }
            set
            {
                if(value == _parent)
                    return;

                if(_parent != null)
                {
                    _parent._children.Remove(this);
                    _parent = null;
                }

                if(value != null)
                {
                    value._children.Add(this);
                    _parent = value;
                }
            }
        }
    }
}

我要问的问题是,是否有任何替代方法可以实现相同的目标,并且比这种方法有更少或更小的缺点?我发现这种方法的主要缺点是:

附带说明一下,这可能是一个很好的例子,说明使用 friend 扩展访问权限可以简化这些问题!

正如我在评论中所述,在父项中添加一个 Remove 方法,这至少不会暴露整个子项列表。类似于:

public class Parent
    {
        private readonly List<Child> _children = new List<Child>();

        public readonly ReadOnlyCollection<Child> Children = _children.AsReadOnly();

        public void Remove(Child child)
        {
            if(child !=null) 
            {
             _children.Remove(child);
            }
        }
    }

当然,如评论和之前的回答所述,您还需要封装将子项添加到父项,这需要 public Add(Child) 方法

我喜欢使用通用的私有接口来公开如下属性:

public class SomeBigOuterClass {
    private interface IChildFriend {
        void SetParent(Parent parent);
    }

    public class Parent {
    }

    public class Child : IChildFriend {
        void IChildFriend.SetParent(Parent parent) {
            this.parent = parent;
        }
        private Parent parent;
    }
}