从 C# 类型变量初始化通用变量 [英] Initializing a Generic variable from a C# Type Variable
问题描述
我有一个类,它将泛型类型作为其初始化的一部分.
I have a class that takes a Generic Type as part of its initialization.
public class AnimalContext<T>
{
public DoAnimalStuff()
{
//AnimalType Specific Code
}
}
我现在能做的就是
AnimalContext<Donkey> donkeyContext = new AnimalContext<Donkey>();
AnimalContext<Orca> orcaContext = new AnimalContext<Orca>();
但是我需要/想要做的是能够声明一个初始化为仅在运行时已知的类型的 AnimalContext.例如,
But what I need/want to do is be able to declare an AnimalContext initialized to a type that is only known at runtime. For instance,
Animal a = MyFavoriteAnimal(); //returns an instance of a class
//implementing an animal
AnimalContext<a.GetType()> a_Context = new AnimalContext<a.GetType()>();
a_Context.DoAnimalStuff();
这甚至可能吗?我似乎无法在网上找到答案.
Is this even possible? I can't seem to find an answer for this online.
推荐答案
这部分的含义是可能的:
new AnimalContext<a.GetType()>();
显然,确切的语法是错误的,我们将继续讨论,但是可以在运行时构造一个泛型类型的实例,如果您不这样做'在运行时之前不知道类型参数.
Obviously that exact syntax is wrong, and we'll get to that, but it is possible to construct an instance of a generic type at runtime when you don't know the type parameters until runtime.
这部分的意思是不是:
AnimalContext<a.GetType()> a_Context
也就是说,如果您在编译时不知道类型参数,就不可能将变量键入为泛型类型.泛型是编译时构造,依赖于在编译时提供的类型信息.鉴于此,如果您在编译时不知道类型,您将失去泛型的所有好处.
That is, it is impossible to type a variable as a generic type if you don't know the type parameters at compile-time. Generics are compile-time constructs, and rely on having the type information available at compile-time. Given this, you lose all the benefits of generics if you don't know the types at compile-time.
现在,当您直到运行时才知道类型时,要在运行时构造泛型类型的实例,您可以说:
Now, to construct an instance of a generic type at runtime when you don't know the type until runtime, you can say:
var type = typeof(AnimalContext<>).MakeGenericType(a.GetType());
var a_Context = Activator.CreateInstance(type);
注意a_context
的编译时类型是object
.您必须将 a_context
转换为定义您需要访问的方法的类型或接口.通常你会看到人们在这里做的是让泛型类型 AnimalContext
实现一些接口(比如 IAnimalContext
)或从定义他们需要的方法的非通用基类(比如 AnimalContext
)(这样你就可以将 a_context
转换为接口或非通用基类).另一种选择是使用 dynamic
.但同样,请记住,这样做没有泛型类型的好处.
Note that the compile-time type of a_context
is object
. You will have to cast a_context
to a type or interface that defines the methods you need to access. Often what you'll see people do here is have the generic type AnimalContext<T>
implement some interface (say IAnimalContext
) or inherit from a non-generic base class (say AnimalContext
) that defines the methods they need (so then you can cast a_context
to the interface or the non-generic base class). Another alternative is to use dynamic
. But again, keep in mind, you have none of the benefits of generic types in doing this.
这篇关于从 C# 类型变量初始化通用变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!