声明一个超类数组



假设我有:

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};

谢谢

你想把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};

不直接(协方差"限制")

但你可以做到

List<A> superTypeList = 
   b_array.Cast<A>()
   .Concat(c_array.Cast<A>())
   .Concat(d_array.Cast<A>())
   .ToList();

你必须列出一个 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));;

更好的方法是使用称为复合模式的设计模式。

实质上,您创建一个基类(组件),其中包含您希望子节点(如果它们又有子节点,则为组合节点,如果它们停止分支,则为叶节点)的所有方法,然后仅实现您希望每个子节点在每个子类型中使用的方法。

在您的情况下,您可以这样做:

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

最新更新