Как получить универсальный метод на закрытом универсальном типе, открыв MethodInfo из открытого универсального типа? - PullRequest
7 голосов
/ 25 сентября 2010

Представьте себе такой тип (C #):

public interface IAmGeneric<T>
{
   void SoAmI<T1>(T one, T1 two);
}

Учитывая, что у меня есть открытый универсальный MethodInfo из открытой универсальной версии типа (IAmGeneric<>.SoAmI<>()) и следующий массив

new[] { typeof(int), typeof(string) }'

Я ищу эффективный и надежный способ получения закрытой версии MethodInfo, такой как:

IAmGeneric<int>.SoAmI<string>()

ОБНОВЛЕНИЕ:

надежной, я имею в виду, что она должна обрабатывать случаикогда метод не является общедоступным, имеет десятки перегрузок, использует общие аргументы базового типа, а не только его непосредственный интерфейс и т. д.

Ответы [ 3 ]

1 голос
/ 25 сентября 2010

Вот пример, который довольно сложен для правильного определения:

public interface IAmGeneric<T>
{
    void SoAmI<T1, T2>(T one, T1 two, T2 three);
    void SoAmI<T1, T2>(T one, T2 two, T1 three);
    void SoAmI<T1, T2>(T1 one, T two, T2 three);
    void SoAmI<T1, T2>(T2 one, T1 two, T three);
    void SoAmI<T1, T2, T3>(T2 one, T1 two, T3 three);
}

Для меня решение состоит в том, чтобы использовать GetMethods(...).Select() и сравнить имя метода, количество параметров, типы и количество параметров типа, чтобы найтиправильный метод (в основном все, что является частью сигнатуры метода).

1 голос
/ 25 сентября 2010

Как то так?Не уверен, что именно вы ищете, может быть, расширите свой вопрос ... Это определенно потребует добавления некоторых проверок (например, проверка, является ли объявление типа универсальным / если метод универсален и т. Д.)

var method = typeof(IAmGeneric<>).GetMethod("SoAmI");
var types = new[] { typeof(int), typeof(string) };


var methodTypeParams = method.GetGenericArguments();
var fullType = method.DeclaringType.MakeGenericType(types.Take(types.Length - methodTypeParams.Length).ToArray());
var fullMethod = fullType.GetMethod(method.Name).MakeGenericMethod(types.Skip(types.Length - methodTypeParams.Length).ToArray());
0 голосов
/ 11 декабря 2015

Используйте MethodBase.GetMethodFromHandle, как указано в этот связанный ответ :

var ty = typeof(IAmGeneric<>);
var numTyParams = ty.GenericTypeArguments.Length;
var mi = ... do something with ty to get generic def for SoAmI<> ...
var parameters = new[] { typeof(int), typeof(string) };
var output = MethodBase.GetMethodFromHandle(mi.MethodHandle, ty.MakeGenericType(parameters.Take(numTyParams).ToArray()).TypeHandle).MakeGenericMethod(parameters.Skip(numTyParams).ToArray());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...