В соответствии с заголовком, можно ли объявить ограничения типа с отрицанием в C# 4?generic NOT constraint, где T:! IEnumerable
ответ
Нет - такой концепции не существует ни на C#, ни в CLR.
Будет ли эта концепция превращаться в C# и/или CLR в будущем? –
@RandRandom: Я не слышал о каких-либо планах. –
Нет, но можно было бы проверить с «это», а затем обработать его соответствующим образом ...
используется ограничение, так что вы можете гарантировать, что тип вы используете имеет некоторые свойства/методы/.. . вы хотите использовать.
Общий тип с отрицательным типом ограничений не имеет никакого смысла, так как нет никакой цели узнать об отсутствии некоторых свойств/методов. вы не хотите использовать.
Очевидно, что вы не получили сообщение об ошибке: ## '
Мне удалось обойти мой сценарий, используя серию абстрактных классов, которые реализуют экземпляр подобного интерфейса и наследуют абстрактный класс. Я полагаю, это как действие
Насколько я знаю, это невозможно сделать.
Что вы можете сделать некоторые проверки времени выполнения:
public bool MyGenericMethod<T>()
{
// if (T is IEnumerable) // don't do this
if (typeof(T).GetInterface("IEnumerable") == null)
return false;
// ...
return true;
}
Вы не можете использовать 'is', как это - он проверяет, совместим ли * объект * с типом. –
Вы имеете в виду 'if (typeof (T) == typeof (IEnumerable)) {}' – kev
один использовать для этого было бы тип опции.
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
}
}
Проверка времени выполнения, конечно, будет работать, но вы не получили бы преимущества проверки типа во время компиляции.
Я нашел себя, пытаясь реализовать тот же случай упоминается в комментариях:
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>());
}
даже если были, вы можете описать случай использования? –
Странно наблюдать, что у вас есть такое требование. вы можете использовать только код типа T, который, как вы знаете, относится к семейству классов. Как вы можете кодировать дженериков в противном случае? Либо вам не нужны дженерики в этом случае, либо вам нужно пересмотреть свои прецеденты. –
Предполагаемый прецедент должен был позволить следующим перегрузкам сосуществовать: void doIt (T what) {} '' void doIt (IEnumerable whats) {} '- на данный момент существует двусмысленность, потому что' T 'в первом методе может быть' IEnumerable <> '(поэтому я хотел бы указать, что' T' НЕ должен быть 'IEnumerable') ... –
Cel