Можно ли ограничить параметр типа универсального метода C #как «назначаемый из» параметра типа содержащего класса?

Я подозреваю, что ответ отрицательный, но я хочу знать, можно ли сделать что-то подобное:

public class MyGenericClass<TSomeClass> {
    public void MyGenericMethod<TSomeInterface>() 
        // This doesn't compile.
        where TSomeClass : TSomeInterface 
    {
        //...
    }
}

То, что я хотел указать в приведенном выше (не-рабочем )примере, — это ограничить TSomeInterfaceтаким образом, чтобы он мог быть любым базовым классом, реализованным интерфейсом или (, если вы действительно хотите придумать )неявное преобразование MyGenericClass.

ПРИМЕЧАНИЕ: Я подозреваю, что причина, по которой это никогда не было реализовано в C #, заключается в том, что общие ограничения не на самом деле предназначены для кодовых контрактов, как я пытаюсь использовать их здесь. Мне действительно все равно, какой тип TSomeInterface, если он реализован TSomeClass.

До сих пор я взломал это вместе:

public class MyGenericClass<TSomeClass> {
    public void MyGenericMethod<TIntermediateType, TSomeInterface>() 
        where TIntermediateType : TSomeClass, TSomeInterface 
    {
        //...
    }
}

Это более или менее обеспечивает соблюдение ограничения, которое я хочу (, которое TSomeClassдолжно наследоваться или, в случае интерфейса, реализовать,TSomeInterface), но вызывать его очень коряво, т.к. надо указатьTIntermediateType(хотя я действительно хочу, чтобы он оценивался поTSomeClass):

var myGenericInstance = new MyGenericClass<TSomeClass>();
myGenericInstance.MyGenericMethod(TSomeClass, TSomeInterface);

Кроме того, приведенный выше хак не работает, потому что вызывающая сторона теоретически может указать подкласс TSomeClassв качестве первого параметра типа, где только подкласс реализует TSomeInterface.

Причина, по которой я хочу это сделать, заключается в том, что я пишу шаблон фабрики Fluent для службы WCF, и мне бы хотелось бы предотвратить попытки вызывающего (во время компиляции )для создания конечной точки с контрактом, который не реализует класс обслуживания. Очевидно, я могу проверить это во время выполнения (. WCF фактически делает это за меня ), но я большой поклонник проверки во время компиляции -.

Есть ли лучший/более элегантный способ добиться того, что мне нужно?

9
задан Chris Shain 29 June 2012 в 15:27
поделиться