Контракт, который гарантирует, что IEnumerable не пуст

Данный код

static public int Q()
{
    return Enumerable.Range(0, 100)
        .Select(i => i)
        .First();
}

выдает следующее предупреждение:

warning : CodeContracts: requires unproven: Any(source)

Если я удаляю предложение .Select(), оно исчезает.

Но мне непонятно, что именно мне нужно .Ensure, чтобы выполнить cccheck.

Ответы

Ответ 1

Вы можете избежать предупреждения с помощью этого кода?

var res = Enumerable.Range(0, 100).Select(i => i).Take(1); //execute one query with TOP1 and store in memory
Contract.Assume(res.Any()); //or res.Count() > 0 //query already in memory
return res.First(); //query already in memory

Ответ 2

Так как это решает проблему и по-прежнему не так уродлива, как можно было подумать вначале, я отправляю ее как ответ (если у меня есть лучшие идеи, которые я раскрываю для ваших предложений):

static public int Q()
{
    var e = Enumerable.Range(0, 100)
        .Select(i => i);

    Contract.Assume(e.Any());
    return e.First();
}

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

Примечание:

по какой-то причине ни

Contract.Assert(e.Count() > 0);

или

Contract.Assert(e.Any());

работа.

Важно. Как отмечают другие люди, это может быть неприемлемо для всех случаев, поскольку дополнительный вызов e.Any() будет реализовывать сбор, что может быть нежелательным в некоторых случаях (например: когда оно LINQ от стороннего источника).