Это действительно имеет отношение к открытым построенным типам.
Когда вы говорите:
class List<T> : IList<T>
Вы на самом деле говорите: мой класс называется List, у него есть один параметр типа с именемT, и он реализует интерфейс, который построен из IList <> с использованием того же T . Таким образом, T в части определения и T в части «Implements» ссылаются на один и тот же параметр типа - вы объявляете его перед двоеточием, а затем сразу же ссылаетесь на него после двоеточия.
Это сбивает с толку, потому что параметр типа IList<>
также называется T - но это совершенно другой параметр типа. Итак, давайте повторно объявим наш конкретный класс следующим образом:
class List<U> : IList<U>
Это полностью эквивалентно вышеприведенному, только теперь мы можем сказать «U», когда мы ссылаемся на параметр типа List, и T, когда мыобратитесь к одному из IList. Это разные типы.
Теперь становится проще понять, почему определение универсального типа List<U>
(что вы имеете в виду, когда говорите typeof(List<>)
) не реализует определение типа generifc IList<T>
(это то, что вы имеете в виду, когда говорите typeof(IList<>)
), но, скорее, он реализует открытый универсальный составной тип IList<U>
(то есть IList, построенный с использованием собственного пареметра типа List).
Таким образом, в основном определения универсальных типов никогда не наследуют и не реализуют определения других универсальных типов - они обычно реализуют открытые составные типы, используя свои собственные параметры типа с другими определениями универсальных типов.
Ответ Ripper234 показывает, как обрабатывать этот конкретный случай с помощью Reflection, поэтому я не буду его повторять;Я просто хотел уточнить взаимосвязь между этими типами, и я надеюсь, что она получилась хотя бы несколько понятной.