2010-02-11 2 views
10

Я пытаюсь сделать это:Как передать переменную типа «типа» для общего параметра

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

, но это не работает, у вас есть какие-либо идеи, как я могу это сделать?

+0

Это невозможно. Как сказал пользователь18636, вы должны использовать отражение. – NotMe

+0

Возможный дубликат [Как использовать отражение для вызова общего метода?] (Http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method) – nawfal

ответ

17

Для этого вам необходимо использовать отражение.

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

Если это метод экземпляра вместо статического метода, то вы передаете переменную Invoke (второй параметр нулевой для массива параметров, которые, как правило, переходят к методу, в случае нуль, как вызов метода без параметров .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<...>() 

Если у вас есть неоднозначное исключение перегрузки это, вероятно, потому, что GetMethod нашел более одного метода с таким именем. В этом случае вместо этого вы можете использовать GetMethods и использовать критерии для фильтрации вниз до требуемого метода. Это может быть отчасти хрупким, хотя, потому что кто-то может добавить еще один метод достаточно похожий на ваши критерии, которые он затем разбивает свой код, когда он возвращает несколько методов:

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

Это не идеально, потому что вы все еще можете иметь некоторую двусмысленность. Я только проверяю счет, и вам действительно нужно проходить через GetParameters и GetGenericArguments и проверять каждый, чтобы убедиться, что он соответствует подписи, которую вы хотите.

Смежные вопросы