如何创建从具有不同类型的相同泛型类继承的对象列表?

时间:2011-08-15 14:59:35

标签: c# generics

我花了几个小时不停地试图找到答案,我可能无法正确处理问题,这没有用。基本上,我有一个抽象类:

public abstract class GenericType<T>
{ ... }

还有一大堆继承自它的类:

public class AType: GenericType<A>
{ ... }

public class BType: GenericType<B>
{ ... }

...

最后,我有另一个类想要包含从GenericType继承的事物列表,无论T的值是什么,即Atypes,BTypes等等。

我的第一次尝试是使用List<GenericType>List<GenericType<Object>>,但是他们给了我任何快乐。

关于我应该怎么做的任何提示?非常感谢!

4 个答案:

答案 0 :(得分:11)

  

如何创建一个通用的对象列表,这些对象被约束为从使用不同类型参数构造的同一泛型类继承?

这在C#类型系统中是不可能的;你只能列出一个实际类型的列表,而不是像“List<U>那样的”类型模式“,其中对于某些未指定的T,U必须是Foo<T>

为了明白为什么不可能,让我们假设这是可能的。我们将“类型模式”注释为问号:

class Stack<T> { ... }
...
List<Stack<?>> listOfStacks = new List<Stack<?>>();
listOfStacks.Add(new Stack<int>());
listOfStacks.Add(new Stack<Giraffe>());

好的,太好了。 现在您打算如何处理堆栈列表?您无法安全地使用涉及堆栈类型参数的堆栈执行任何

listOfStacks[0].Push("hello");

这应该在编译时失败,因为插槽零中的堆栈是一堆int而不是字符串。 编译器如何知道?编译器无法知道。通过允许此功能,您实际上破坏了编译器对您的程序进行类型检查的能力。

回答“我怎么做这个不可能的事情?”知道为什么你想做不可能的事情是有帮助的。而不是试图做这个不可能的事情告诉我们你真正想做什么,看看是否有人能解决真正的问题。

答案 1 :(得分:8)

所以,如果我理解正确,你想要这样的东西:

List<GenericType>

其中可以包含ATypeBType等任何实例。您只需将GenericType<T>本身作为GenericType的子类:

即可。
public class GenericType { }
public class GenericType<T> : GenericType { }
public class AType : GenericType<int> { }
public class BType : GenericType<int> { }

然后您可以将任何实例粘贴到List<GenericType>中。

答案 2 :(得分:3)

如果GenericType<T>实施了非通用接口IAmNotGeneric,那么ATypeBType都可以添加到List<IAmNotGeneric>

public abstract class GenericType<T> : IAmNotGeneric

同样的原则可以应用于非泛型抽象基类。

public abstract class GenericType<T> : NonGenericType

答案 3 :(得分:0)

您的意思是列表中包含每个派生类型的实例吗?

Assembly.GetExecutingAssembly().GetTypes
    .Where(type => type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(GenericType<>))
    .ToList().
    .ForEach(type => list.Add(Activator.CreateInstance(type)));