Обобщения встроены в C #, так что это «настоящее улучшение».Следовательно, почему возможны ковариация и противоречивость во время выполнения, а также рефлексия на универсальных типах и создание универсальных типов на основе рефлексии во время выполнения (например, List<T>
, где T определяется во время выполнения).
Это отличается от C ++, где шаблоны во многих отношениях являются синтаксическим сахаром.Компилятор фактически генерирует код для каждого используемого вами универсального типа - поэтому Add<T>
создаст Add<int>
, Add<long>
, Add<short>
, Add<MyClass>
и т. Д., Если вы используете эти функции, и аналогично для классов.Преимущество этого - прежде всего операторы и несколько других более мелких вещей - если у каждого из этих типов есть оператор +, а Add<T>(T a, T b)
возвращает a + b, все типы будут работать нормально.Компилятор C # будет жаловаться, потому что он не может / не разрешает объявление оператора для всех типов во время компиляции.Более того, C # (не уверен на 100%, но, возможно, на 90%) создает 1 реализацию универсального типа для ссылочных типов (если вы используете эту реализацию), а затем 1 для каждого типа значения (например, int, long, Decimal, MyStruct и т. Д. Allполучить свои собственные реализации по мере необходимости).