Initializing a Generic variable from a C# Type Variable

前端 未结 3 842
我在风中等你
我在风中等你 2020-12-02 18:04

I have a class that takes a Generic Type as part of its initialization.

public class AnimalContext
{
    public DoAnimalStuff()
    {
        //Anim         


        
相关标签:
3条回答
  • 2020-12-02 18:43

    You can use reflection with generic type by using MakeGenericType method and take adavantage of dynamic keyword:

    var type = typeof (AnimalContext<>).MakeGenericType(a.GetType());
    dynamic a_Context = Activator.CreateInstance(type);
    

    So you can call:

    a_Context.DoAnimalStuff();
    

    Or use reflection again to call method:

    type.GetMethod("DoAnimalStuff").Invoke(a_Context, null);
    
    0 讨论(0)
  • 2020-12-02 18:43

    You would need to create the type using Reflection and then invoke that type. Something like:

    Animal a = MyFavoriteAnimal();
    var contextType = typeof(EsbRepository<>).MakeGenericType(a.GetType());
    
    dynamic context = Activator.CreateInstance(contextType);
    context.DoAnimalStuff();
    

    The use of dynamic means that the context variable will be evaluated at run time allowing for you to call the DoAnimalStuff method.

    0 讨论(0)
  • 2020-12-02 18:45

    What you mean by this part is possible:

    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.

    What you mean by this part is not:

    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);   
    

    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.

    0 讨论(0)
提交回复
热议问题