2012-01-04 1 views
36

В соответствии с заголовком, можно ли объявить ограничения типа с отрицанием в C# 4?generic NOT constraint, где T:! IEnumerable

+6

даже если были, вы можете описать случай использования? –

+1

Странно наблюдать, что у вас есть такое требование. вы можете использовать только код типа T, который, как вы знаете, относится к семейству классов. Как вы можете кодировать дженериков в противном случае? Либо вам не нужны дженерики в этом случае, либо вам нужно пересмотреть свои прецеденты. –

+2

Предполагаемый прецедент должен был позволить следующим перегрузкам сосуществовать: void doIt (T what) {} '' void doIt (IEnumerable whats) {} '- на данный момент существует двусмысленность, потому что' T 'в первом методе может быть' IEnumerable <> '(поэтому я хотел бы указать, что' T' НЕ должен быть 'IEnumerable') ... – Cel

ответ

36

Нет - такой концепции не существует ни на C#, ни в CLR.

+0

Будет ли эта концепция превращаться в C# и/или CLR в будущем? –

+0

@RandRandom: Я не слышал о каких-либо планах. –

0

Нет, но можно было бы проверить с «это», а затем обработать его соответствующим образом ...

1

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

Общий тип с отрицательным типом ограничений не имеет никакого смысла, так как нет никакой цели узнать об отсутствии некоторых свойств/методов. вы не хотите использовать.

+0

Очевидно, что вы не получили сообщение об ошибке: ## '' не может реализовать как «>», так и «>», поскольку они могут объединяться для некоторых подстановок ##. . Конечно, есть случаи, когда вы хотите указать, что genericstype2 не может быть generictype4 –

+0

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

4

Насколько я знаю, это невозможно сделать.

Что вы можете сделать некоторые проверки времени выполнения:

public bool MyGenericMethod<T>() 
{ 
    // if (T is IEnumerable) // don't do this 

    if (typeof(T).GetInterface("IEnumerable") == null) 
     return false; 

    // ... 

    return true; 
} 
+1

Вы не можете использовать 'is', как это - он проверяет, совместим ли * объект * с типом. –

+2

Вы имеете в виду 'if (typeof (T) == typeof (IEnumerable)) {}' – kev

0

один использовать для этого было бы тип опции.

public class Option<A,B> 
where A : !B 
where B : !A 
{ 
    private readonly A a; 
    private readonly B b; 

    private Option(){} 

    public Option(A a) 
    { 
     this.a = a 
    } 

    public Option(B b) 
    { 
     this.b = b 
    } 
} 

Проверка времени выполнения, конечно, будет работать, но вы не получили бы преимущества проверки типа во время компиляции.

2

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

void doIt<T>(IEnumerable<T> what) { } 
void doIt<T>(T whats) { } 

I Освобожденные следующий код для ссылки на первый метод:

doIt(new List<T>()); 

Но это фактически ссылки второй.

Одним из решений является гипсе Аргумент так:

doIt(new List<T>().AsEnumerable<T>()); 

Бросок может быть скрыт другой перегрузки:

void doIt<T>(List<T> whats) { 
    doIt(whats.AsEnumerable<T>()); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^