2016-04-14 2 views
15

Данный кодконтракта, что обеспечивает IEnumerable не является пустым

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

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

warning : CodeContracts: requires unproven: Any(source) 

Если удалить .Select() положение он исчезает.

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

+0

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

+1

@Viru это минимальный жизнеспособный пример созданного специально для демонстрации проблемы. В реальном коде есть целые методы LINQ. – zerkms

+1

@Szeki https://github.com/Microsoft/CodeContracts – zerkms

ответ

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 
+0

Да, это определенно является улучшением моего ответа (для случаев, когда использование '.Any()' может быть нежелательным). – zerkms

1

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

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 от 3 участника источник).

+1

Возможно, вы должны использовать' Contract.Assume (e.Any()); 'просто для хорошей формы. –

+0

Как сказал @Wicher Visser в комментарии к вопросу; разделение 'Select' и' First' приведет к; т. е. структура сущностей; не включая TOP1 в сгенерированном SQL-запросе и ущемляет производительность. – jlvaquero

+0

@jlvaquero не так ли? – zerkms

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