Использовали ли вы обобщенные типы (generics) в C#?

«Использовали ли вы обобщенные типы (generics) в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, активно использовал. Generics — это фундаментальный инструмент в C# для создания типобезопасных и производительных компонентов без дублирования кода.

Основные сценарии применения:

  1. Работа с коллекциями. Использование List<T>, Dictionary<TKey, TValue>, Queue<T> вместо небезопасных коллекций вроде ArrayList исключает упаковку/распаковку (boxing/unboxing) для value-типов и ошибки приведения типов.
  2. Создание обобщенных методов. Позволяет писать алгоритмы, работающие с разными типами.
    public T GetMax<T>(T first, T second) where T : IComparable<T>
    {
        return first.CompareTo(second) > 0 ? first : second;
    }
    // Использование: GetMax(5, 10); GetMax("abc", "xyz");
  3. Разработка обобщенных классов. Например, шаблон репозитория или сервиса для работы с различными сущностями.
    public interface IRepository<T> where T : class, IEntity
    {
        Task<T?> GetByIdAsync(int id);
        Task AddAsync(T entity);
    }

Ключевые преимущества:

  • Безопасность типов: Ошибки несоответствия типов обнаруживаются на этапе компиляции.
  • Производительность: Для value-типов исключаются накладные расходы на boxing.
  • Повторное использование кода: Один обобщенный алгоритм или компонент работает со множеством типов.

Ограничения (constraints): С помощью ключевого слова where можно задавать ограничения, например where T : struct (только value-типы), where T : new() (должен иметь открытый конструктор по умолчанию) или where T : SomeInterface.