Как получить `Type.GenericParameterPosition` для параметра метода типа class-generi c - PullRequest
1 голос
/ 01 мая 2020

Получить параметр GenericParameterPosition для параметра легко, если его тип является аргументом общего типа c метода:

public class MyClass {
    public void Foo<T>(T a) { }
}

// ...

Console.WriteLine("pos: " + typeof(MyClass)
    .GetMethod("Foo")
    .GetParameters()
    .Single()
    .ParameterType
    .GenericParameterPosition);

pos: 0

Но как мы можем выполнить sh это для параметра, тип которого является аргументом общего типа c класса ?

public class MyClass<T> {
    public void Foo(T a) { }
}

// ...

Console.WriteLine("pos: " + typeof(MyClass<int>)
    .GetMethod("Foo")
    .GetParameters()
    .Single()
    .ParameterType
    .GenericParameterPosition);

InvalidOperationException: Метод может вызываться только для типа, для которого Type.IsGenericParameter имеет значение true.

1 Ответ

1 голос
/ 01 мая 2020

MyClass<int> - это сконструированный тип , поэтому в отношении времени выполнения параметр Foo равен int, а не универсальный c параметр , Сравните это с универсальным c методом Foo<T>, где среда выполнения не знает, что такое тип T, и знает только, что это параметр generi c.

Поэтому вам следует использовать открытый тип, такой как MyClass<>:

Console.WriteLine("pos: " + typeof(MyClass<>)
    .GetMethod("Foo")
    .GetParameters()
    .Single()
    .ParameterType
    .GenericParameterPosition);

Таким образом, тип параметра Foo распознается как универсальный параметр c.

Вы также можете использовать GetGenericTypeDefnition чтобы изменить составной тип на открытый тип:

Console.WriteLine("pos: " + typeof(MyClass<int>)
    .GetGenericTypeDefinition()
    ...

Это полезно, если объект Type приходит откуда-то, что вы не можете контролировать.

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