我正在艰难地讨论如何最好地解决这个问题,并且非常希望得到专家社区的一些指导!
假设我有3个班级
Branch
Twig
Leaf
Branch
可以包含其他Branch
个对象的集合,但也可以包含Twig
个对象和Leaf
个对象的集合。
Twig
可以包含其他Twig
个对象的集合,但也可以包含Leaf
个对象的集合。
Leaf
对象可以被视为基本组件,不包含任何其他对象的集合。
因此,可能的结构是
分支
Branch Branch Branch
| | |
|_Branch |_Twig |_Leaf
| |_etc... | |_etc...
| |
|_Twig |_Leaf
| |_etc...
|
|_Leaf
枝条
Twig Twig
| |
|_Twig |_Leaf
| |_etc...
|
|_Leaf
叶
Leaf
鉴于Branch
,我希望能够查询任何后代Branch
,Twig
或Leaf
个对象并知道
每个后代对象对顶层对象的贡献率(在每种情况下,该比率与父对象和子对象相关)。
如果特定类型的后代对象包含特定属性值。例如,检查后代Leaf
个对象,看是否有超过4个UnderSide
属性值"Furry"
我也希望能够选择
3.一次性通过对象列出一个后代级别,即所有第一个孩子的有序列表,然后是所有第二个孩子等等(每个级别中对象的顺序无关紧要)。
我的第一个想法是使用通用树和接口多态,但我在编制细节时遇到困难 - Twig
和Leaf
对象共享一些常见属性但Branch
对象是非常不同的。如果我只处理一种类型的对象,那将非常简单!这可以以类型安全的方式完成吗?
非常感谢任何帮助。
答案 0 :(得分:3)
我会用接口来决定谁可以持有什么:
public interface IBranch { }
public interface ITwig { }
public class Branch : IBranch
{
List<IBranch> _Kids = new List<IBranch>();
public List<IBranch> Kids
{
get { return _Kids; }
}
}
public class Twig : ITwig, IBranch
{
List<ITwig> _Kids;
public List<ITwig> Kids
{
get { return _Kids; }
}
}
public class Leaf : ITwig, IBranch
{
}
实现ienumerable并确保在枚举子项之前“收益返回”。将所有常用功能放在IBranch中,以及ITwig中leaf和twig之间的通用性会很好。
希望这有帮助!
答案 1 :(得分:1)
他们都会共享比率属性但不是它们,所以你至少可以让它们都实现一些IRatio接口......
答案 2 :(得分:1)
这就是我可能会这样做的方式:
public interface INodeChild
{
public INodeParent Parent {get;set;}
//Any methods/properties common to ALL inheritors
}
public abstract class NodeParent : INodeChild
{
public INodeParent Parent {get; protected set;}
public IList<INodeChild> Children {get;set;}
// This is just breadth-wise since I'm more familiar with that.
public string ListChildren(int level)
{
StringBuilder sb = new StringBuilder();
foreach(INodeChild item in Children)
{
sb.AppendLine(Enumerable.Repeat(" ", level));
INodeParent itemParent = item as INodeParent;
if(itemParent != null)
{
itemParent.ListChildren(++level);
}
}
return sb.ToString();
}
//Any methods/properties common to all parent inheritors (brach/twig/etc)
}
public class Brach : NodeParent
{
// Any branch only stuff goes here.
}
public class Twig : NodeParent
{
// Any twig only stuff goes here
}
public class Leaf : INodeChild
{
// Any leaf only stuff goes here.
}