Как передать переменную типа «Тип» в универсальный параметр - PullRequest
10 голосов
/ 11 февраля 2010

Я пытаюсь сделать это:

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

но это не работает, ты не представляешь, как я мог это сделать?

Ответы [ 2 ]

17 голосов
/ 11 февраля 2010

Для этого нужно использовать отражение.

var method =
    typeof(MetaDataUtil)
    .GetMethod("GetColumnasGrid")
    .MakeGenericMethod(new [] { type })
    .Invoke(null, null);
3 голосов
/ 20 декабря 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...