Здравствуйте, vorona, Вы писали:
V>Почему сравнение по типу возвращает false, а по токену true;
Ну, я могу сказать что пошло не так, но объяснения у меня пока нет.
class Typed<T> { }
class Some
{
public static Typed<T> Method<T>() => null;
}
static void Main(string[] args)
{
var m = typeof(Some).GetMethod(nameof(Some.Method));
var typeDefinition = typeof(Typed<>);
Console.WriteLine("Reflected method is generic definition: {0}", m.IsGenericMethodDefinition); // true
Console.WriteLine("Return type is generic definition: {0}", m.ReturnType.IsGenericTypeDefinition); // false, no idea why
Console.WriteLine("typeof() result is generic definition: {0}", typeDefinition.IsGenericTypeDefinition); // true
Console.WriteLine("done.");
Console.ReadKey();
}
Выглядит как хороший вопрос для StackOverflow
UPD А, ну да, всё логично, это я стормозил. Как обычно, используем подход "что было бы, если?".
Итак, предположим, что для метода
Typed<T> Method1<T>() return type был бы unbound-генерик-тип
Typed<>. Т.е. .ReturnType.IsGenericTypeDefinition был бы true.
Неожиданно, ну да фиг с ним.
Проблема в другом: что должен возвращать returntype для метода с вот такой вот сигнатурой:
T Method2<T>()?
Придётся вернуть тип-заглушку, не null же
Так вот, это "непонятно что вернуть, но должно быть T" используется и во всех остальных вариантах, для Method1 — как генерик-параметр для return type. Т.е. return type уже не unbound и .ReturnType.IsGenericTypeDefinition становится false, что мы и наблюдаем.
Чтоб точно не осталось вопросов: какой тип возвращаемого значения должен быть для
Typed<T, int> Method3<T>(), если учитывать, что CLR не разрешает partial-bound generics?
P.S. Для любителей покопаться в кишках и освежить память:
https://alexandrnikitin.github.io/blog/dotnet-generics-under-the-hood/
http://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti#21
http://joeduffyblog.com/2011/10/23/on-generics-and-some-of-the-associated-overheads/