我花了几个小时不停地试图找到答案,我可能无法正确处理问题,这没有用。基本上,我有一个抽象类:
public abstract class GenericType<T>
{ ... }
还有一大堆继承自它的类:
public class AType: GenericType<A>
{ ... }
public class BType: GenericType<B>
{ ... }
...
最后,我有另一个类想要包含从GenericType继承的事物列表,无论T的值是什么,即Atypes,BTypes等等。
我的第一次尝试是使用List<GenericType>
和List<GenericType<Object>>
,但是他们给了我任何快乐。
关于我应该怎么做的任何提示?非常感谢!
答案 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>
其中可以包含AType
,BType
等任何实例。您只需将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
,那么AType
和BType
都可以添加到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)));