Как устранить неоднозначность метода generi c в отражении C# - PullRequest
1 голос
/ 26 мая 2020

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

// Argument types
public class Bar<T> {}
public class Bar<T, U> {}

// Generic method overloads
private static void Foo<T> (Bar<T> b) {}
private static void Foo<T, U> (Bar<T, U> b) {}

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

BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Static;

// Should give Foo<int>
GetType ().GetMethod ("Foo", Flags).MakeGenericMethod (typeof(int));

// Should give Foo<int, int>
GetType ().GetMethod ("Foo", Flags | BindingFlags.Static).MakeGenericMethod (typeof(int), typeof(int));

Однако это не удается с System.Reflection.AmbiguousMatchException .

Я попытался указать такие вещи, как new Type[] {typeof (Bar<,>)} в качестве types аргумент для некоторых из GetMethod перегрузок, но результат всегда был нулевым. Я знаю, что могу обойти двусмысленность, просто используя разные имена для функций, но мне интересно узнать, есть ли реальное решение для этого.

Я нахожусь. NET стандарт 2.0,. NET Ядро 2,0

1 Ответ

0 голосов
/ 27 мая 2020

Если вы не хотите использовать Type.GetMethods и перебирать результаты, вы можете использовать эту перегрузку GetMethod и Type.MakeGenericMethodParameter, доступную по адресу. NET Core 2.1:

class MyClass
{
    // Argument types
    public class Bar<T> { }
    public class Bar<T, U> { }

    // Generic method overrides
    private static void Foo<T>(Bar<T> b) { }
    private static void Foo<T, U>(Bar<T, U> b) { }
}

typeof(MyClass)
    .GetMethod(
    "Foo",
    1,
    BindingFlags.NonPublic | BindingFlags.Static,
    null,
    new[] { Type.MakeGenericSignatureType(typeof(MyClass.Bar<>), Type.MakeGenericMethodParameter(0)) },
    null
); // First Foo

typeof(MyClass)
    .GetMethod(
    "Foo",
    2,
    BindingFlags.NonPublic | BindingFlags.Static,
    null,
    new[] { Type.MakeGenericSignatureType(typeof(MyClass.Bar<,>), Type.MakeGenericMethodParameter(0),Type.MakeGenericMethodParameter(1)) },
    null
); // Second Foo

UPD

Поскольку Type.MakeGenericMethodParameter недоступен для вас, единственный вариант, который я вижу (если каждый метод не является частью generi c class с тем же generi c type argumetns) должен использовать GetMethods и фильтровать результаты. Самым простым фильтром в этом случае будет количество общих c параметров;

var secondMethod = typeof(MyClass).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
    .Where(mi => mi.Name == "Foo" && mi.GetGenericArguments().Length == 2)
    .First();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...