Обобщения
Обобщения – это механизм многократного использования алгоритма. Разработчик описывает алгоритм, но не указывает типы данных, с которыми тот работает. Применяя алгоритм, другой разработчик должен указать конкретные типы данных. Например, обобщённый список определяется как List<T>. Здесь переменная T, указывающая на тип называется параметром типа. В объявлении обобщённого типа её можно использовать в любом месте, где указывается, тип данных. Например:
- в параметре метода
public void Add(T item);
- в возвращаемом значенииpublic T[] ToArray();
public T this[int index] { get; set; }
- при определении локальных переменных и полей внутри классаMicrosoft рекомендует называть параметры типа
T или словом, начинающимся с T (TKey, TResult). При этом рекомендуется использовать значимые имена, где это возможно или если параметр типа ограничен конкретным классом или интерфейсом (например, параметр типа, ограниченный интерфейсом ISession, может быть назван TSession).Преимущества обобщений:
- защита исходного кода: для использования обобщённого алгоритма не нужен доступ к исходному тексту алгоритма;
- безопасность типов: компилятор и CLR обеспечивают, чтобы в алгоритме использовались лишь объекты, совместимые с указанным типом данных;
- более простой и понятный код: из-за того, что компилятор обеспечивает безопасность типов уже на этапе компиляции, требуется меньше операций приведения типов, а такой код проще писать и поддерживать;
- повышение производительности: не требуется лишних операций приведения типов, для структур не требуется упаковки/разупаковки, что ускоряет работу кода.
Наиболее частым видом использования обобщённых типов являются коллекции, такие как связанные списки, хэш-таблицы, стеки, очереди, деревья и т.п. Операции, вроде добавления и удаления элементов коллекции, выполняются примерно одинаково вне зависимости от типа хранимых данных. В большинстве случаев, когда требуется класс коллекции, рекомендуется использовать классы, определённые в библиотеке классов .NET.
При создании ваших собственных обобщённых типов, важно учитывать следующие моменты:
1. Какие типы обобщать в параметры типа. Обычно, чем больше типов вы параметризуете, тем более гибким становится ваш код. Но слишком обобщённый тип может привести к коду, который будет трудно читать и понять другим разработчикам.
2. Какие ограничения, если они нужны, применить к параметрам типа (об ограничениях в следующих постах). Хорошим тоном будет применить максимально возможные ограничения, которые всё равно позволят вам использовать требуемые типы. Например, если обобщённый тип подразумевает использование только ссылочных типов, добавьте ограничение
class. Это не допустит использования вашего типа со структурами.3. Обдумайте обобщённое поведение в базовом классе и подклассах.
4. Нужно ли реализовать один или больше обобщённых интерфейсов. Например, если вы разрабатываете класс, который будет использоваться в качестве элемента обобщённой коллекции, вам может потребоваться реализовать интерфейс вроде
IComparable<T>, где T – это тип вашего класса.Продолжение следует…
Источники:
- Джеффри Рихтер “CLR via C#”. 3-е изд. – СПб.: Питер, 2012. Глава 12.
- https://docs.microsoft.com/ru-ru/dotnet/csharp/programming-guide/generics/index