Можно ли ограничить параметр универсального типа тем, что принимает другой параметр универсального типа?
Например:
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
,