Что такое обобщения (generics) в C#?

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

Ответ

Обобщения (generics) — это механизм, позволяющий создавать классы, структуры, интерфейсы и методы с параметрами типа. Это обеспечивает строгую типизацию на этапе компиляции и исключает необходимость приведения типов или операций упаковки/распаковки для значимых типов.

Основные преимущества:

  1. Безопасность типов: Компилятор проверяет соответствие типов, предотвращая ошибки времени выполнения.
  2. Производительность: Для значимых типов (int, double, struct) не происходит упаковки (boxing). Код работает напрямую с конкретным типом.
  3. Повторное использование кода: Один обобщённый алгоритм может работать с разными типами данных.

Пример обобщённого класса:

public class Repository<T> where T : class, IEntity, new() // Ограничения
{
    private List<T> _items = new List<T>();

    public T GetById(int id) => _items.FirstOrDefault(item => item.Id == id);
    public void Add(T entity) => _items.Add(entity);
}

// Использование с конкретными типами
var userRepo = new Repository<User>(); // T становится User
var productRepo = new Repository<Product>(); // T становится Product
userRepo.Add(new User { Id = 1, Name = "Alice" });

Пример обобщённого метода:

public static T Max<T>(T a, T b) where T : IComparable<T>
{
    return a.CompareTo(b) > 0 ? a : b;
}

int result = Max(10, 20); // T выводится как int
string textResult = Max("abc", "xyz"); // T выводится как string

Ограничения (constraints): Позволяют указать требования к параметру типа, открывая соответствующие операции.

  • where T : struct — T должен быть значимым типом.
  • where T : class — T должен быть ссылочным типом.
  • where T : new() — T должен иметь открытый конструктор без параметров.
  • where T : BaseClass — T должен наследоваться от BaseClass.
  • where T : ISomeInterface — T должен реализовывать интерфейс ISomeInterface.