«Входящие» параметры универсального класса и параметры универсального метода могут комбинировать типы, но нет возможности для переменных или полей представлять «составные» типы.Кроме того, чтобы передать объект параметру универсального типа, который объединяет несколько ограничений, объект должен быть приведен к типу, который фактически реализует все эти ограничения.Это может быть сложно.
Например, предположим, что класс Foo
и Bar
оба реализуют Intf1
и Intf2
.Хочется написать функцию AddToList<T>(thing as T) where T:Intf1,Intf2
.Такая функция прекрасно подходит для объектов типа Foo
или Bar
.Предположим, однако, что кто-то хочет использовать такую функцию для добавления всех объектов в один и тот же список (который может быть смесью Foo
, Bar
и любого числа других типов, которые также могут реализовывать Intf1
и Intf2
), а затем передают эти объекты в функцию, параметр которой также ограничен для реализации Intf1
и Intf2
.Можно привести к Foo
любой объект, который оказался Foo
, и привести к Bar
любой объект, который оказался Bar
, но если записаны другие типы, которые также обрабатывают Intf1
и Intf2
, было бы трудно иметь с ними дело.
Возможно, решить проблему несколько неловко, не используя Reflection или другие подобные трюки.Определите интерфейс IActUpon<Base1, Base2>
с помощью метода ActUpon<thingType>ActUpon(thingType thing) where thingType: Base1, Base2
.Реализации такого метода смогут передавать параметр thing
другим методам, для которых требуется универсальный параметр метода, ограниченный Base1
и Base2
.Самые большие трудности при таком подходе состоят в том, что нужно написать отдельный код для каждого возможного числа ограничений, и что во многих местах, где можно было бы использовать лямбда-выражение, вместо этого придется написать реализацию IActUpon...
.