Когда у нас будет что-то вроде этого:
interface ISomething<U,V> { ... }
class Something<U,V> : ISomething<U,V> { ... }
typeof (ISomething <,>)
и typeof (Something <,>)
приведет к «определению универсального типа». Но если мы перейдем к типу интерфейса как к интерфейсу, реализованному классом, это будет сконструированный тип, и ни один из его параметров типа на самом деле не связан:
typeof(Something<,>).GetInterfaces().SingleOrDefault()
MSDN конкретно упоминает об этом. Я хочу создать тот же тип (сконструированный тип) ISomething <,>
напрямую (без подкласса и поиска базового типа), и я не мог найти никакого способа сделать это .
Дополнительная информация:
Я даже пробовал это:
Type t1 = typeof(ISomething<,>);
Type t2 = t1.MakeGenericType(t1.GetGenericArguments()) // Yields a generic type definition
Type t3 = typeof(Something<,>).GetInterfaces().SingleOrDefault();
В приведенном выше коде:
t1.Equals (t2)
верно, но t1.Equals (t3)
ложно, очевидно, потому что t3
построено.
Удивительно, но t1.GetGenericArguments () [0] .Equals (t3.GetGenericArguments () [0])
ложно, хотя оба открыты (IsGenericParameter = true), и я не смог найти любое различие в их свойствах.
И вот почему мне нужно это сделать: мне нужна каноническая форма хранения объектов Type в списке. Объекты иногда поступают из базовых классов / интерфейсов (например, t3 выше), а иногда напрямую (например, t1). Мне нужно будет сравнить их друг с другом. Я не могу сохранить определение универсального типа (используя .GetGenericTypeDefinition ()
), потому что иногда у меня будет частично открытый сконструированный универсальный тип (например, ISomething), и GetGenericTypeDefinition предоставит мне тип без каких-либо указанных аргументов типа .
Единственный способ сделать типы каноническими, который, как я думал, мог бы работать, - это проверить, все ли аргументы типа не связаны, и выполнить GetGenericTypeDefinition. В противном случае сохраните сконструированный тип.