2010-09-26 1 views
1

Есть ли способ применить несколько разных общих ограничений csharp к тому же типу, где тест OR, а не AND?Есть ли способ применить общие ограничения C#, а не совместно?

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

В приведенном ниже примере я мог бы написать несколько методов с одним ограничением, которые все вызовут один и тот же метод Swim, но мне интересно, есть ли способ написать один метод с несколькими непересекающимися ограничениями.

Например

interface IAnimal 
{ 
    bool IsWet { get; set; } 
    bool IsDrowned { get; set; } 
} 

public static class SwimmingHelpers 
{ 
    /*this is the psuedo effect of what I would like to achieve*/ 
    public static void Swim<T>(this T animalThatCanSwim) 
    where T: IAnimal, Human | 
    where T: IAnimal, Fish | 
    where T: IAnimal, Whale .... 
} 

FYI Реальный сценарий я поигрывая в HTML элементы, которые все реализуют интерфейс IElement, но я хочу предназначаться только те элементы, где определенные типы поведения, действительные в HTML спецификации и не более конкретных общих интерфейс реализуется ими, например: элементами, которые могут иметь атрибут readonly.

+0

Почему бы не создать общий интерфейс? – PostMan

+0

Потому что это сторонняя библиотека. Я просто изучаю, как использовать дженерики, а также методы расширения, избегая при этом повторения :-) –

+0

Достаточно справедливо, я просто принимаю IAnimal, а затем бросаю ArgumentException из не требуемого типа – PostMan

ответ

1

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

0

В дженериках нет оператора OR.

Но вы всегда можете ввести новый интерфейс для захвата подмножества классов, т.е. IReadOnly. Это может быть интерфейс маркера, который не определяет какие-либо методы. Со временем вы можете найти некоторое использование для этих новых интерфейсов ...

+2

Я обычно, используя новый интерфейс, мог бы пойти, но OP не может этого сделать, поскольку типы из сторонней библиотеки. –

3

Не с generics. Можно, однако, получить то, что вы хотите, определив простые перегрузки, как это:

public static class SwimmingHelpers { 
    public static void Swim(this Human animalThatCanSwim) { 
     SwimInternal(animalThatCanSwim); 
    } 
    public static void Swim(this Fish animalThatCanSwim) { 
     SwimInternal(animalThatCanSwim); 
    } 
    public static void Swim(this Whale animalThatCanSwim) { 
     SwimInternal(animalThatCanSwim); 
    } 
    private static void SwimInternal(IAnimal animalThatCanSwim) { 
     // do your work here, no duplication of the code needed 
    } 
} 
Смежные вопросы