Когда вы создаете универсальный тип, вы создаете концептуальный «шаблон», а не полный тип. Он может стать полным типом, только если вы укажете недостающие части в шаблоне: конкретные типы.
Существуют ограничения типа, поэтому компилятор может добавить некоторую проверку типов. Даже если вы не знаете тип точный , который будет использоваться, если он наследуется от базы, вы знаете, какие члены базы доступны для вашего кода. Если вы попытаетесь ограничить параметр типа универсальным типом без аргументов типа, компилятору не хватит информации, чтобы понять, какие методы действительно будут доступны.
Например, если мы заменим TB: B
на тип TB: List<T>
, компилятор не будет знать, из какого списка. Методы типа Add(T)
и Remove(T)
не могут быть скомпилированы, потому что T
будет неизвестен.
Чтобы ограничения типов были полезными, они должны ограничивать систему типов таким образом, чтобы добавлять полезную информацию. Единственный способ, чтобы эта информация была полезной, - это конкретный тип.