Можно ли ограничить параметр универсального типа тем, что принимает другой параметр универсального типа?

Например:

class ClassA<TA> where TA: T1, T2, T3, T4 ...
{
}

class ClassB<TB> where TB: whatever ClassA.TA accepts
{
  ClassA<TB> MyA;
}

Я не хочу копировать ограничение ClassA в ClassB из-за принципов SSoT и DRY.

3 ответа

Решение

Вы можете сделать это, если будет приемлемо, чтобы ClassB был публичным внутренним классом ClassA. Это довольно не элегантно и некрасиво.

public class ClassA<T> where T : IDisposable
{
    public ClassA(T thing)
    {
        ThingA = thing;
    }
    public T ThingA { get; set; }
    public class ClassB
    {
        public ClassB(T thing)
        {
            ThingB = thing;
        }
        public T ThingB { get; set; }
    }
}

Это позволяет мне использовать этот (ужасный) синтаксис:

var b = new ClassA<Stream>.ClassB(stm);

Я думаю, что вам лучше написать два очевидных модульных теста, которые используют Type.GetGenericParameterConstraints чтобы гарантировать, что ClassA и ClassB синхронизированы.

Если бы я контролировал определения типов, я бы использовал общий интерфейс.

public interface IBase { }

public class T1 : IBase { }
public class T2 : IBase { }

public class ClassA<TA> where TA: IBase { }
public class ClassB<TB> where TB: IBase { }

В противном случае C# не поддерживает макросы препроцессора, неявные интерфейсы или псевдонимы ограничений, поэтому вам нужно будет скопировать и вставить ограничения.

Не существует механизма языка C#, который бы делал это. Лучшее, на что вы могли бы надеяться, это то, что какой-то сторонний инструмент потенциально может перечислить их для вас, но это, конечно, не будет оставаться в курсе любых изменений в ClassA,

Другие вопросы по тегам