在c#中实现树管理父子关系
我正在实现一个树,将其视为一个文件夹结构,因此我有一个类似以下的类:在c#中实现树管理父子关系,c#,nhibernate,design-patterns,tree,C#,Nhibernate,Design Patterns,Tree,我正在实现一个树,将其视为一个文件夹结构,因此我有一个类似以下的类: public class Folder { //Various Props like Name etc. public IList<Folder> Children{get;} public Folder Parent {get;} } 公共类文件夹 { //各种道具,如名字等。 公共IList子项{get;} 公用文件夹父项{get;} } 现在我想要的是能够在树上走来走去,这样给定一
public class Folder
{
//Various Props like Name etc.
public IList<Folder> Children{get;}
public Folder Parent {get;}
}
公共类文件夹
{
//各种道具,如名字等。
公共IList子项{get;}
公用文件夹父项{get;}
}
现在我想要的是能够在树上走来走去,这样给定一个根,我就能找到一片叶子,给定一片叶子,我就能找到根节点。所以每个孩子都需要一个父母。现在的问题是,向树中添加新节点的最佳方式是什么。我过去使用过两种解决方案:
我很好奇人们通常使用什么模式,然后如果有人对我的特定用例有任何建议。我正在使用nHibernate将我的树持久化到SQL server。我不希望实现自定义集合,因为它需要大量的代码才能使它在我的应用程序中的一小部分工作 就个人而言,我会选择方法1。在任何情况下,允许客户端代码直接操作子集合都会违反封装,因此“锁定”子集合是正确的™.
保持节点关系正确的“适当”策略取决于客户的需求。我假设在这种特定情况下,您希望客户端能够更改子节点本身,但不能更改子集合。如果是这样的话,我认为Rob Prouse的建议(让孩子们的财产返回一个IEnumerable)可能是最好的选择。在其他情况下,ReadOnlyCollection可能会更好。我会选择选项1,然后使Children属性如下所示:
public IEnumerable<Folder> Children
{
get { return this.children.GetEnumerator(); }
}
公共IEnumerable子项
{
get{返回this.children.GetEnumerator();}
}
现在必须调用AddChild来添加子项。集合不可访问。使用数字1,但要使您的子属性IEnumerable,以便用户无法添加到集合。查看后,您可以尝试以下操作:
List<Folder> children;
public ReadOnlyCollection<Folder> Children
{
get { return this.children.AsReadOnly(); }
}
列出子项;
公共只读集合子项
{
获取{返回this.children.AsReadOnly();}
}
如果您的私有成员必须声明为IList,那么我们可以将其复制到列表中,然后返回它。但我真的不认为作为私有成员使用具体实现有什么问题。以后更改实现不会破坏兼容性
IList<Folder> children;
public ReadOnlyCollection<Folder> Children
{
get
{
return new List<Folder>(this.children).AsReadOnly();
}
}
IList儿童;
公共只读集合子项
{
得到
{
返回新列表(this.children).AsReadOnly();
}
}
实现自定义集合需要大量工作;实现一个只公开两个或三个方法的现有集合类的包装器是不可能的。从你对JayArr的反应来看,这似乎就是你想要的。比如:
public class ChildCollection
{
// _Children is maintained by the Folder class, hence the internal access specifier
internal Dictionary<KeyType, Folder> _Children = new Dictionary<KeyType, Folder>;
public this[KeyType key]
{
get
{
return _Children[key];
}
}
public IEnumerable<KeyType> Keys
{
get
{
return _Children.Keys;
}
}
}
公共类ChildCollection
{
//_子项由Folder类维护,因此是内部访问说明符
内部字典_Children=新字典;
公开此[密钥类型密钥]
{
得到
{
返回子项[键];
}
}
公共IEnumerable密钥
{
得到
{
返回_Children.key;
}
}
}
那么您如何防止他们修改集合?你用什么策略?只读集合?返回集合副本?@Josh:返回IEnumerable的一种方法:public IEnumerable子项{get{foreach(子项中的文件夹子项){yield Return child;}}}嗯,只要客户端不想索引到IList,nice就可以正常工作……如果您的孩子是一本词典,它就会崩溃……只有当您使用列表时;-)IList不支持这一点。没错。但就我所见,没有一个接口指定一个只读列表。所以要么使用更通用的IEnumerable,要么就失去索引。或者返回ReadOnlyList的子代并更改您的私有实现。任何其他解决方案都需要编写您自己的类/接口我添加了一个新的解决方案,适合您的所有需求:-)我正在寻找nHibernate和更一般的想法…有一个很好的帖子,其中有人删除了一个集合。。。