Есть ли способ применить общие ограничения c # по отдельности, а не совместно? - PullRequest
1 голос
/ 27 сентября 2010

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

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

В приведенном ниже примере я мог бы написать несколько методов, каждый из которых имел бы одно ограничение, и все они вызывали бы один и тот же метод 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, и для них не реализован более конкретный общий интерфейс, например: может иметь атрибут только для чтения.

Ответы [ 3 ]

3 голосов
/ 27 сентября 2010

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

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
   } 
}
1 голос
/ 27 сентября 2010

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

0 голосов
/ 27 сентября 2010

В обобщениях нет оператора ИЛИ.

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

...