Шаг 264.
Язык программирования C#. Начала.
Обобщенные типы. Ограничения на параметры типа (продолжение)

    На этом шаге мы рассмотрим еще один пример задания ограничения.

    Еще один пример использования ограничения для обобщенного параметра типа представлен в примере ниже. На этот раз ограничение состоит в том, что значением обобщенного параметра может быть только класс, у которого есть конструктор без аргументов.


Когда возникает необходимость накладывать ограничение, связанное с наличием конструктора без аргументов? Например, в обобщенном классе создается объект обобщенного типа. Нужно вызвать конструктор класса, который обозначен как обобщенный параметр.

    Если мы уверены, что у этого класса есть конструктор без аргументов, то можем вызвать такой конструктор, даже не зная, с каким классом в действительности придется иметь дело. А уверенными мы можем быть, если наложим ограничение, которое состоит в том, что у класса, являющегося значением обобщенного параметра, есть конструктор без аргументов.


    Рассмотрим представленный далее программный код.

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();      .
То есть объект создается инструкцией new T(), в которой мы обобщенный параметр T используем как имя класса. Собственно, ради возможности использовать данную инструкцию на параметр 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";
полям объектов, на которые есть ссылка в поле obj, присваиваются значения. После этого командами
  objA.show(); 
и
  objB.show(); 
проверяется результат.

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг