Можно ли в C# объявить обобщенный класс (generic) с более чем одним параметром типа?

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

Ответ

Да, в C# можно использовать произвольное количество универсальных параметров типа (type parameters), разделяя их запятыми в угловых скобках <>. Это применяется в классах, структурах, интерфейсах и методах.

Примеры:

  1. Класс с двумя параметрами (аналог KeyValuePair<TKey, TValue>):

    public class Result<TData, TError>
    {
        public bool IsSuccess { get; init; }
        public TData? Data { get; init; }
        public TError? Error { get; init; }
    
        public static Result<TData, TError> Success(TData data) => 
            new() { IsSuccess = true, Data = data };
        public static Result<TData, TError> Failure(TError error) => 
            new() { IsSuccess = false, Error = error };
    }
    // Использование:
    Result<Order, string> operationResult = Result<Order, string>.Success(new Order());
  2. Метод с несколькими параметрами типа:

    public TOutput Transform<TInput, TOutput>(TInput input, Func<TInput, TOutput> mapper)
    {
        return mapper(input);
    }
    // Использование:
    int number = 42;
    string text = Transform<int, string>(number, n => n.ToString());
  3. Интерфейс с ограничениями (constraints) для разных параметров:

    public interface IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>
    {
        TEntity? GetById(TKey id);
        void Add(TEntity entity);
    }
    // Реализация:
    public class UserRepository : IRepository<User, int> { /* ... */ }

Рекомендации:

  • Именуйте параметры типа понятно (например, TKey, TValue, TResult), особенно когда их много.
  • Используйте ограничения (where), чтобы сделать код более типобезопасным и читаемым.
  • Хотя формальных ограничений нет, чрезмерное количество параметров (более 3-4) часто сигнализирует о сложности дизайна, который стоит пересмотреть.