На этом шаге мы рассмотрим еще один пример задания ограничения.
Еще один пример использования ограничения для обобщенного параметра типа представлен в примере ниже. На этот раз ограничение состоит в том, что значением обобщенного параметра может быть только класс, у которого есть конструктор без аргументов.
Если мы уверены, что у этого класса есть конструктор без аргументов, то можем вызвать такой конструктор, даже не зная, с каким классом в действительности придется иметь дело. А уверенными мы можем быть, если наложим ограничение, которое состоит в том, что у класса, являющегося значением обобщенного параметра, есть конструктор без аргументов.
Рассмотрим представленный далее программный код.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr264_1 { // Первый класс: class Alpha { public int code; public override string ToString() { return "Alpha: " + code; } } // Второй класс: class Bravo { public string text; public override string ToString() { return "Bravo: " + text; } } // Обобщенный класс с ограничением на обобщенный параметр: class MyClass <T> where T: new() { // Ссылка на объект: public T obj; // Конструктор: public MyClass() { // Создание объекта обобщенного типа: obj = new T(); } // Метод: public void show() { Console.WriteLine(obj); } } // Главный класс: class Program { // Главный метод: static void Main() { // На основе обобщенного класса создается объект: MyClass<Alpha> objA = new MyClass<Alpha>(); objA.obj.code = 123; objA.show(); // На основе обобщенного класса создается объект: MyClass<Bravo> objB = new MyClass<Bravo>(); objB.obj.text = "text"; objB.show(); // Задержка: Console.ReadLine(); } } }
Результат выполнения программы показан ниже:
Рис.1. Результат работы приложения
В программе описаны обычные классы Alpha (с целочисленным полем code) и Bravo (с текстовым полем text). В каждом классе переопределен метод ToString(). Метод результатом возвращает текстовую строку с названием класса и значением поля. Ни в одном из классов не описан конструктор, и это означает, что каждый класс имеет конструктор без аргументов.
Обобщенный класс MyClass имеет один обобщенный параметр T, на который наложено ограничение where T: new(). Оно означает, что класс, который будет использован как значение обобщенного параметра (при создании объекта на основе обобщенного класса), должен иметь конструктор без аргументов. Классы Alpha и Bravo удовлетворяют этому критерию.
В обобщенном классе MyClass имеется поле obj обобщенного типа T. Значением полю присваивается ссылка на объект, который создается при вызове конструктора. Соответствующая команда имеет вид
obj = new T(); .
У обобщенного класса MyClass есть метод show(). При его вызове в консольном окне "печатается" объект, на который ссылается поле obj (в этом случае для объекта obj вызывается метод ToString()).
В методе Main() на основе обобщенного класса MyClass создаются два объекта: при создании объекта objA значением обобщенного параметра является класс Alpha, а при создании объекта objB значением обобщенного параметра является класс Bravo. У каждого из объектов objA и objB есть поле obj. Для объекта objA поле obj ссылается на объект класса Alpha, а для объекта objB поле obj ссылается на объект класса Bravo. Командами
objA.obj.code = 123;
objB.obj.text = "text";
objA.show();
objB.show();
На следующем шаге мы продолжим изучение этого вопроса.