ryudice
ryudice

Reputation: 37366

How to pass variable of type "Type" to generic parameter

I'm trying to do this:

Type type = Type.GetType(string.Format("Gestor.Data.Entities.{0}, Gestor.Data", e.Item.Value));
MetaDataUtil.GetColumnasGrid<type>();

but it's not working, do you have any idea how I could do this?

Upvotes: 10

Views: 5852

Answers (2)

AaronLS
AaronLS

Reputation: 38367

If it is an instance method instead of a static method, then you pass the variable to Invoke(the second parameter null is for an array of parameters that you would usually pass to the method, in the case of null is like calling a method with no parameters .GetColumnAsGrid()):

Type genericTypeParameter = Type.GetType(string.Format("Gestor.Data.Entities.{0}, Gestor.Data", e.Item.Value));
MetaDataUtil someInstance = new MetaDataUtil();

var returnResult =
    typeof(MetaDataUtil)
    .GetMethod("GetColumnsAsGrid")
    .MakeGenericMethod(new [] { genericTypeParameter })
    .Invoke(someInstance, null);//passing someInstance here because we want to call someInstance.GetColumnsAsGrid<...>()

If you have ambiguous overload exception it's probably because GetMethod found more than one method with that name. In which case you can instead use GetMethods and use criteria to filter down to the method you want. This can be kind of fragile though because someone might add another method similar enough to your criteria that it then breaks your code when it returns multiple methods:

var returnResult = 
    typeof(MetaDataUtil)
    .GetMethods().Single( m=> m.Name == "GetColumnsAsGrid" && m.IsGenericMethod 
        && m.GetParameters().Count() == 0 //the overload that takes 0 parameters i.e. SomeMethod()
        && m.GetGenericArguments().Count() == 1 //the overload like SomeMethod<OnlyOneGenericParam>()
    )
    .MakeGenericMethod(new [] { genericTypeParameter })
    .Invoke(someInstance, null);

This isn't perfect because you could still have some ambiguity. I'm only checking the count and you'd really need to iterate through the GetParameters and GetGenericArguments and check each one to make sure it matches the signature that you want.

Upvotes: 4

Derek Slager
Derek Slager

Reputation: 13831

You need to use reflection for this.

var method =
    typeof(MetaDataUtil)
    .GetMethod("GetColumnasGrid")
    .MakeGenericMethod(new [] { type })
    .Invoke(null, null);

Upvotes: 18

Related Questions