我有一个像这样声明的抽象类BaseItem:
public abstract class BaseItem
{
public BaseItem Parent { get; protected set; }
public List<BaseItem> Children = new List<BaseItem>();
public abstract string Function1();
}
基本上,我正在尝试实现一个设计,其中每个Item都有一个特定类型的父级和不同类型的子级。
例如,ItemA将拥有所有ItemB类型的子项。然后ItemB将具有ItemA类型的父级和子级所有ItemC类型。 ItemC将具有ItemB的父级和ItemD类型的子级。
我认为使用泛型来做这件事会更加简洁,以避免不必要的演员表,因为我知道我的每个继承类的父和子将是什么类型。所以我想出了类似的东西:
public abstract class AbstractBase
{
public abstract string Function1();
}
public abstract class BaseItem<T1, T2> : AbstractBase
where T1 : AbstractBase
where T2 : AbstractBase
{
public T1 Parent { get; protected set; }
public List<T2> Children = new List<T2>();
}
public class ItemA : BaseItem<ItemA, ItemB>
{
}
public class ItemB : BaseItem<ItemA, ItemC>
{
}
public class ItemC : BaseItem<ItemB, ItemD>
{
}
public class ItemD : BaseItem<ItemC, ItemD>
{
}
所以有两件事。 这是一个好设计吗?这样做有更简单/更好的方法吗?我真的不喜欢使用第二个抽象基类只是为了能够使用泛型。 如果我确实这样做,处理目的的最佳方法是什么? (即ItemA在我的实际问题域中没有父级,但它需要一个父级来编译.ProjectD没有子级,但我需要给它一些东西)
答案 0 :(得分:1)
如果我理解你的话,你说ItemA
永远不会有父母而且ItemD
从来没有孩子,对吗?说实话,我可能只是声明具有正确类型的父/子属性的单独类:
public abstract class AbstractBase
{
public abstract string Function1();
}
public class ItemA : AbstractBase
{
public List<ItemB> Children = new List<ItemB>();
}
public class ItemB : AbstractBase
{
public ItemA Parent { get; protected set; }
public List<ItemC> Children = new List<ItemC>();
}
public class ItemC : AbstractBase
{
public ItemB Parent { get; protected set; }
public List<ItemD> Children = new List<ItemD>();
}
public class ItemD : AbstractBase
{
public ItemC Parent { get; protected set; }
}
您在这里重复的唯一事情是Parent
和Children
属性/字段。您可以在AbstractBase
中实现的所有其他常用功能。 (当然,除非该功能需要访问父母/孩子 - 但即使在您的解决方案中,您也会回到原点。)
答案 1 :(得分:1)
我会这样做:
public interface IChildOf<T> {
T Parent { get; set; }
}
public interface IParent<T> {
List<T> Children { get; set; }
}
//This class handles all of the cases that have both parent and children
public abstract class BaseItem<T1, T2> : IParent<T1>, IChildOf<T2>
{
public List<T1> Children { get; set; }
public T2 Parent { get; set; }
}
//This class handles the top level parent
public class ItemA : IParent<ItemB>
{
public List<ItemB> Children { get; set; }
}
public class ItemB : BaseItem<ItemC, ItemA>
{
}
public class ItemC : BaseItem<ItemD, ItemB>
{
}
//.... as many intermediates as you like.
//This class handles the bottom level items with no children
public class ItemD : IChildOf<ItemC>
{
public ItemC Parent { get; set; }
}
答案 2 :(得分:0)
您可以使用两个通用接口ChildOf<T>
和IList<T>
。这将让您处理最终案例。不幸的是,由于.NET没有多重继承,您将无法共享实现。
或者你可以使用抽象类和标记类型(System.Void
是理想的,但我不认为它会编译)最终的情况,并从Parent
检查它/ Children
属性并抛出异常。
答案 3 :(得分:0)
这似乎不是一个糟糕的想法,虽然说实话,我很想保留最初的解决方案,并忍受铸造,因为它确实增加了相当复杂,没有那么多的好处。 (虽然我必须承认,我会尽可能地用通用代替替换。)
如果你确实想保留它,可以提出几点建议:
显然,第二点只会增加复杂性,这是我不确定它是否值得的另一个原因。
答案 4 :(得分:0)
我没有看到以这种方式做事的问题,因为您似乎有一个特定的层次结构要求顶级项目为ItemA
类型,第二级项目为{{1}类型1}}等等。
要解决根节点和叶节点,我可能会定义也来自ItemB
的单独类:
AbstractBase