Обобщения

Разработчикам хорошо известны достоинства объектно-ориентированного программирования. Одно из ключевых преимуществ — возможность многократного использования кода за счет создания производных классов, наследующих все возможности базового класса. В производном классе можно просто переопределить виртуальные методы или добавить новые методы, чтобы изменить унаследованные от базового класса характеристики для решения новых задач. Обобщения (generics) — еще один механизм, поддерживаемый средой CLR и языками программирования для другой разновидности многократного использования кода — а именно многократного использования алгоритмов.

По сути, разработчик описывает алгоритм, например, сортировки, поиска, замены, сравнения или преобразования, но не указывает типы данных, с которыми тот работает, что позволяет применять алгоритм к объектам разных типов. Применяя готовый алгоритм, другой разработчик должен указать конкретные типы данных, например для алгоритма сортировки — Int32, String и т. д., а для алгоритма сравнения — DateTime, Version и т. д.

FCL-класс, инкапсулирующий обобщенный алгоритм управления списками, называется List<T> и определен в пространстве имен System.Collections.Generic. Исходный текст определения этого класса выглядит следующим образом (приводится с сокращениями):

[Serializable] public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>,   
    IList, ICollection, IEnumerable {

    public List();  
    public void Add(T item);  
    public Int32 BinarySearch(T item);  
    public void Clear();
    public Boolean Contains(T item);  

    public Int32 IndexOf(T item);  
    public Boolean Remove(T item);  
    public void Sort();  
    public void Sort(IComparer<T> comparer);  
    public void Sort(Comparison<T> comparison);  
    public T[] ToArray();
    public Int32 Count { get; }  
    public T this[Int32 index] { get; set; }
 }

Символами <T> сразу после имени класса автор обобщенного класса List указал, что класс работает с неопределенным типом данных. При определении обобщенного типа или метода переменные, указанные вместо типа (например, T), называются параметрами типа (type parameters). T — это имя переменной, которое применяется в исходном тексте во всех местах, где используется соответствующий тип данных. Например, в определении класса List переменная T служит параметром (метод Add принимает параметр типа T) и возвращаемым значением (метод ToArray возвращает одномерный массив типа T) метода. Другой пример — метод-индексатор (в C# он называется this). У индексатора есть метод доступа get, возвращающий значение типа T, и метод доступа set, получающий параметр типа T. Переменную T можно использовать в любом месте, где должен указываться тип данных — а значит, и при определении локальных переменных внутри метода или полей внутри типа.

Приемущества обобщений:

  • Защита исходного кода. Разработчику, использующему обобщенный алгоритм, не нужен доступ к исходному тексту алгоритма (при работе с шаблонами C++ разработчику, использующему алгоритм, необходим его исходный текст).
  • Безопасность типов. Когда обобщенный алгоритм применяется с конкретным типом, компилятор и CLR понимают это и следят за тем, чтобы в алгоритме использовались лишь объекты, совместимые с этим типом данных. Попытка использования несовместимого объекта приведет к ошибке на этапе компиляции или исключению во время выполнения.
  • Более простой и понятный код. Поскольку компилятор обеспечивает безопасность типов, в исходном тексте требуется меньше операция приведения типов, а такой код проще писать и сопровождать.
  • Повышение производительности. До появления обобщений один из способов определения обобщенного алгоритма заключался в таком определении всех его членов, чтобы они «умели» работать с типом данных Object

results matching ""

    No results matching ""