Контракт, который гарантирует, что 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 от стороннего источника).