Console.WriteLine("Значение: " + str);
Эта программа дает следующий результат.
К типу Т относится' System.Int32 Значение: 102
К типу Т относится System.String
Значение: Обобщения повышают эффективность.
Внимательно проанализируем эту программу. Прежде всего обратите внимание на объявление класса Gen в приведенной ниже строке кода:
class Gen<T> {
где Т — это имя параметра типа. Это имя служит в качестве метки-заполнителя конкретного типа, который указывается при создании объекта класса Gen. Следовательно, имя Т используется в классе Gen всякий раз, когда требуется параметр типа. Обратите внимание на то, что имя Т заключается в угловые скобки (< >). Этот синтаксис можно обобщить: всякий раз, когда объявляется параметр типа, он указывается в угловых скобках. А поскольку параметр типа используется в классе Gen, то такой класс считается обобщенным.
В объявлении класса Gen можно указывать любое имя параметра типа, но по традиции выбирается имя Т. К числу других наиболее употребительных имен параметров типа относятся V и Е. Вы, конечно, вольны использовать и более описательные имена, например TValue или ТКеу. Но в этом случае первой в имени параметра типа принято указывать прописную букву Т.
Далее имя Т используется для объявления переменной ob, как показано в следующей строке кода.
Т ob; // объявить переменную типа Т
Как пояснялось выше, имя параметра типа Т служит меткой-заполнителем конкретного типа, указываемого при создании объекта класса Gen. Поэтому переменная ob будет иметь тип, привязываемый к Т при получении экземпляра объекта класса Gen. Так, если вместо Т указывается тип string, то в экземпляре данного объекта переменная ob будет иметь тип string.
А теперь рассмотрим конструктор класса Gen.
public Gen(T о) { ob = о;
}
Как видите, параметр о этого конструктора относится к типу Т. Это означает, что конкретный тип параметра о определяется типом, привязываемым к Т при создании объекта класса Gen. А поскольку параметр о и переменная экземпляра ob относятся к типу Т, то после создания объекта класса Gen их конкретный тип окажется одним и тем же.
С помощью параметра типа Т можно также указывать тип, возвращаемый методом, как показано ниже на примере метода GetOb ().
public Т GetOb() {
return ob;
}
Переменная ob также относится к типу Т, поэтому ее тип совпадает с типом, возвращаемым методом GetOb ().
Метод ShowType () отображает тип параметра Т, передавая его оператору typeof. Но поскольку реальный тип подставляется вместо Т при создании объекта класса Gen, то оператор typeof получит необходимую информацию о конкретном типе.
В классе Generics Demo демонстрируется применение обобщенного класса Gen. Сначала в нем создается вариант класса Gen для типа int.
Gen<int> iOb;
Внимательно проанализируем это объявление. Прежде всего обратите внимание на то, что тип int указывается в угловых скобках после имени класса Gen. В этом случае int служит аргументом типа, привязанным к параметру типа Т в классе Gen. В данном объявлении создается вариант класса Gen, в котором тип Т заменяется типом int везде, где он встречается. Следовательно, после этого объявления int становится типом переменной ob и возвращаемым типом метода GetOb ().
В следующей строке кода переменной iOb присваивается ссылка на экземпляр объекта класса Gen для варианта типа int.