Подтвердить что ты не робот

Generic NOT constraint, где T:! IEnumerable

В соответствии с заголовком, можно ли объявлять ограничения типа с отрицанием в С# 4?

4b9b3361

Ответ 1

Нет - нет такого понятия ни в С#, ни в CLR.

Ответ 2

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

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

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

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

    // ...

    return true;
}

Ответ 3

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

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>());
}

Ответ 4

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

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

Ответ 5

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

Ответ 6

одно использование для этого будет вариантом типа.

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
    }
} 

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