假设我有:
class A {
//field, properties and common methods
}
class B : A {
//specific ones
}
class C : A {
//specific ones
}
class D : A {
//specific ones
}
然后是这3个列表:
List<B> b_list = new List<B>();
List<C> c_list = new List<C>();
List<D> d_list = new List<D>();
我需要一个指向b_list
,c_list
和d_list
的列表。是否可以考虑B,C,D类具有相同的超类A?
类似的东西:
List<A>[] lists = new[] {b_list, c_list, d_list};
谢谢
答案 0 :(得分:2)
您希望将List<B>
,List<C>
和List<D>
视为List<A>
的子类,但事实并非如此。他们唯一常见的超类型是object
。
在.NET 4及更高版本中,您可以将这些类型全部引用转换为IEnumerable<A>
,因为IEnumerable<out T>
接口在T
中是协变的。在.NET 4.5中,添加了两个协变接口:IReadOnlyList<out T>
和IReadOnlyCollection<out T>
,因此您也可以将它们视为IReadOnlyList<A>
和IReadOnlyCollection<A>
。其中一个界面可能适合您的需求。
类在.NET中不能协变,并且如果该类型参数仅用于“输出”位置,则接口只能在类型参数中协变。换句话说,方法IList<T>.Add(T item)
会阻止IList<>
协变。
因此,假设.NET 4.5:
,可以执行此操作IReadOnlyList<A>[] lists = new[] {b_list, c_list, d_list};
在.NET 4中,你可以做到这一点,它的用处相当少,但可能足以满足你的需求:
IEnumerable<A>[] lists = new[] {b_list, c_list, d_list};
答案 1 :(得分:1)
您必须列出A列表并将b,c,d对象分配给它。您必须将子类对象强制转换为父类A.这将产生限制,您将只访问从基类继承的属性和方法等。
List<B> blist = new List<B>();
List<C> cList = new List<C>();
List<D> dList = new List<D>();
List<List<A>> arrays = new List<List<A>>();
arrays.Add(b_array.ConvertAll(c=>(A)c));;
答案 2 :(得分:1)
不直接(covariance“限制”)
但你可以做到
List<A> superTypeList =
b_array.Cast<A>()
.Concat(c_array.Cast<A>())
.Concat(d_array.Cast<A>())
.ToList();
答案 3 :(得分:0)
更好的方法是使用名为Composite Pattern的设计模式。
基本上,您创建了一个基类(Component),其中包含您希望子节点的所有方法(如果Compisites Nodes反过来有子节点或Leaf节点,如果它们停止分支),那么只需要实现方法希望每个人都能在每种儿童类型中使用。
在您的情况下,您可能会这样做:
abstract class A {
//All methods for all classes
//ex.
public abstract void b();
public abstract void c();
public abstract void d();
}
class B : A {
public override void b()
{
//Do Something
}
public override void c()
{
throw new Exception("Not Implemented");
}
public override void d()
{
throw new Exception("Not Implemented");
}
}
class C : A {
public override void b()
{
throw new Exception("Not Implemented");
}
public override void c()
{
//Do Something
}
public override void d()
{
throw new Exception("Not Implemented");
}
}
class D : A {
public override void b()
{
throw new Exception("Not Implemented");
}
public override void c()
{
throw new Exception("Not Implemented");
}
public override void d()
{
//Do Something
}
}
然后根据多态的定律,如果你做了类似下面的事情,那么应该保留派生类(b,c,d等)的方法。
List<B> blist = new List<B>();
List<C> cList = new List<C>();
List<D> dList = new List<D>();
List<List<A>> arrays = new List<List<A>>();