2

假设我有:

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_list的列表d_list。是否有可能考虑到 B、C、D 类具有相同的超类 A?

就像是:

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

谢谢

4

4 回答 4

2

您想将List<B>List<C>List<D>视为 的子类List<A>,但它们不是。它们唯一常见的超类型是object.

在 .NET 4 及更高版本中,您可以将这些类型全部引用转换为IEnumerable<A>,因为IEnumerable<out T>接口在T. 在 .NET 4.5 中,添加了另外两个协变接口:IReadOnlyList<out T>and IReadOnlyCollection<out T>,因此您也可以将它们视为IReadOnlyList<A>and 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};
于 2012-10-05T23:26:51.070 回答
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));;
于 2012-10-05T22:56:15.683 回答
1

不直接(协方差“限制”)

但你可以做

List<A> superTypeList = 
   b_array.Cast<A>()
   .Concat(c_array.Cast<A>())
   .Concat(d_array.Cast<A>())
   .ToList();
于 2012-10-05T23:00:58.057 回答
0

更好的方法是使用一种称为Composite Pattern的设计模式。

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

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

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>>();
于 2012-10-05T23:42:28.320 回答