有时我发现自己经常写一个“父母”和“孩子”的数据结构,其中:
- 一个父级引用了 0 到 N 个不同的子级。
- 一个孩子有 0 个父母或 1 个父母的参考。
- 引用必须是相互的。对于任何给定的父母,它引用的任何孩子也必须引用给定的父母。对于任何给定的孩子,它引用的父母必须引用给定的孩子。
private
除了使用反射之外,通过使用可从两个类声明(非)外部访问的成员来违反上述规则是不可能的。
在实施这样的事情之前可能采取的心理步骤可能会从这样的事情开始:
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._children
is private
. 但是,除了私有之外,您不想让它成为任何东西,因为允许外部访问Child
或Parent
可能会违反实现或其他地方的规则。
所以,我想出的一个解决方案是嵌套Child
在Parent
. 嵌套类可以访问其嵌套的类的私有成员:
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;
}
}
}
}
}
我要问的问题是,是否有任何替代方法来编写它来实现相同的目标,这些目标比这种方法具有更少或更少的重大缺陷?我发现这种方法的主要缺点是:
- 这可能会导致大型脚本,尽管使用
partial
可以提供帮助。 - 这可能导致比预期更深的嵌套。
- 这可能导致冗长的类名。要访问
Child
外部Parent
,您必须使用Parent.Child
. 在类名很长的情况下,尤其是在使用泛型时,这可能会导致代码非常难看。 - 使用泛型(例如,实现编译时类型安全)可能会变得混乱。这似乎至少部分源于
Child
嵌套Parent<T1>.Child
的事实,Parent<T2>.Child
并且与 .安全性(尽管它可以被封装掉,通常,例如,使用public
访问器所在的非泛型抽象基protected
)。
附带说明一下,这可能是一个很好的例子,说明使用friend
扩展访问权限可以简化这些问题!