Pull to refresh

Обобщения C#

Reading time3 min
Views11K

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

Пример использования обобщений

Представим ситуацию, что заказчик дал нам работу в виде создания ПО для работы с продажей различных видов товаров, по различной цене.

Все мы знаем (а может предстоит узнать), что заказчики очень изменчивые люди в плане своих проектов. Сегодня он скажет сделать цену в виде целого числа, а завтра ему понадобятся еще и копейки в виде дробной.

Что делать в таком случае? Переписывать логику? Ведь если мы изменим тип данных, то вся программа сломается и будет куча ошибок из-за несоответствия типов в классе "продажи".

Выход из данной ситуации есть - и то это шаблоны!

Пример реализации

Давайте рассмотрим приведенный выше пример подробнее и реализуем его на практике

Реализация без шаблонов

Начнём с того, что мы не знаем, про обобщения и реализуем поставленную задачу без них.

Опишем поставленную задачу:

Программа имеет возможность продажи различных продуктов по заданной цене , например “хлеб” за 45 рублей. Исходя из этого можно понять, что мы имеем некий класс, назовем его Product , который имеет поля - Name (наименование продукта ), Price (цена продукта) и один метод Sell (метод продажи). (Рис.1)

Рис.1 Код класса Product
Рис.1 Код класса Product

Попробуем использовать написанный код

Создадим продукт , который будет являться хлебом , стоить он будет 45 рублей ( целое число), затем вызовем метод Sell() (Рис.2)

Рис.2 Код работы с классом Product
Рис.2 Код работы с классом Product

Запустим программу и увидим , что мы продали хлеб за 45 рублей. (Рис.3)

Рис.3 Вывод программы
Рис.3 Вывод программы

Проблема, которая может возникнуть

А теперь представим , что заказчик сообщил о том, что цену на хлеб необходимо указать с копейками.

У нас есть (пока что) лишь один выход из данной ситуации - изменить всю логику класса , задав тип данных вместо целого числа (int) - дробное (float). Действительно, если проделать данные действия , то заказчик будет удовлетворён , но что если логика продажи будет очень большой и нам из-за прихоти заказчика придется все переписывать? так как лично я достаточно ленивый человек - делать этого мне не очень будет хотеться.

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

Использование обобщений

Угловые скобки в описании class Product<T> указывают, что класс является обобщенным, а тип T, заключенный в угловые скобки, будет использоваться этим классом. Необязательно использовать именно букву T, это может быть и любая другая буква. Причем сейчас на этапе написания кода нам неизвестно, что это будет за тип, это может быть любой тип. Поэтому параметр T в угловых скобках еще называется универсальным параметром, так как вместо него можно подставить любой тип.

Изменим структуру нашего класса с использованием обобщения (Рис.4)

Рис.4 использование обобщения в классе Product
Рис.4 использование обобщения в классе Product

Теперь мы увидим ошибку в методе Main (Рис.5)

Рис.5 Ошибка
Рис.5 Ошибка

Данная ошибка появилась из-за того, что мы не используем int как было раньше, теперь мы используем обобщение с типом , следовательно нам необходимо, изменить объявление объекта класса Product, следующим образом (Рис.6)

Рис.6 Обновленный код
Рис.6 Обновленный код

В угловых скобках мы указали тип данных double , исходя из этого цена продукта T Price в классе Product, грубо говоря подставит тип данных double вместо T и в последующем будет его использовать.

Запустим программу и увидим, что мы продали товар за 45.5 рублей (Рис.7)

Рис.7 Вывод программы
Рис.7 Вывод программы

Теперь, мы можем для цены Price использовать любой тип данных для каждого нового объекта класса, например создадим новый объект и в качестве T укажем тип данных string

Создадим объект класса Product<string> назовем его milk и укажем название name - "Молоко", а цену Price - "Нет в наличии. 0 рублей", затем вызовем метод Sell (Рис.8)

Рис.8 новый объект класса
Рис.8 новый объект класса

Запустим программу и увидим, что все работает (Рис.9)

Рис.8 Запуск программы
Рис.8 Запуск программы

В рамках такого небольшого примера, трудно 'разойтись', но думаю в целом стало немного понятнее.

Также ярким примером использования шаблонов можно назвать всем известный класс List<T> , данный класс не знает с каким типом данных он будет работать заранее и при передаче в качестве любого типа данных, логика не поломается. А вот если бы класс шаблоны не использовал, то для каждого нового типа данных пришлось бы создавать копию класса с практически идентичной логикой, но просто переделанной под другой тип

Вывод

Обобщения присутствует во многих языках программирования. Шаблонизация используется фактически во всех динамических структурах языка C# (списки, очереди, стеки и т. д). Знание этого инструмента программирование поможет вам создавать более универсальные структуры и алгоритмы

Ссылки

Код примера можно найти тут

Канал на дзене

Tags:
Hubs:
Total votes 15: ↑5 and ↓10-3
Comments9

Articles