声明一个超类数组

时间:2012-10-05 22:52:32

标签: c# .net arrays class superclass

假设我有:

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_listc_listd_list的列表。是否可以考虑B,C,D类具有相同的超类A?

类似的东西:

List<A>[] lists = new[] {b_list, c_list, d_list};

谢谢

4 个答案:

答案 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>>();