如何创建从具有不同类型的相同泛型类继承的对象列表?
本文关键字:泛型类 继承 列表 对象 同类型 何创建 创建 | 更新日期: 2023-09-27 18:05:43
我花了几个小时断断续续地试图找到这个问题的答案,我可能在正确措辞问题上遇到了麻烦,这没有帮助。实际上,我有一个抽象类:
public abstract class GenericType<T>
{ ... }
和一堆从它继承的类:
public class AType: GenericType<A>
{ ... }
public class BType: GenericType<B>
{ ... }
...
最后,我有另一个类,它想包含从GenericType继承的东西的列表,而不管T的值是什么,即Atypes, BTypes等等。
我的第一次尝试是使用List<GenericType>
和List<GenericType<Object>>
,但都没有给我任何乐趣。
我该怎么做,有什么建议吗?很多谢谢!
如何创建一个对象的泛型列表,这些对象被约束从使用不同类型参数构造的相同泛型类继承?
这在c#类型系统中是不可能的;您只能创建一个实际类型的列表,而不是"类型模式"的列表,例如"List<U>
,其中U对于某些未指定的T必须是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");
应该在编译时失败,因为slot 0中的堆栈是整型堆栈,而不是字符串。编译器是怎么知道的?编译器无法知道。通过允许这个特性,您从本质上破坏了编译器对程序进行类型检查的能力。
要回答"我如何做这件不可能的事?"知道为什么你想做这件不可能的事是有帮助的。而不是试图做这些不可能的事情告诉我们你真正想做什么,看看是否有人能解决真正的问题
所以,如果我理解正确的话,你想要这样的东西:
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>
中。
如果GenericType<T>
实现了一个非通用接口IAmNotGeneric
,那么AType
s和BType
s都可以添加到List<IAmNotGeneric>
中。
public abstract class GenericType<T> : IAmNotGeneric
同样的原则也可以应用于非泛型抽象基类。
public abstract class GenericType<T> : NonGenericType
您是指每个派生类型都有一个实例的列表吗?
Assembly.GetExecutingAssembly().GetTypes
.Where(type => type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(GenericType<>))
.ToList().
.ForEach(type => list.Add(Activator.CreateInstance(type)));