确保 IEnumerable 不为空的合同
Contract that ensures the IEnumerable is not empty
给定的代码
static public int Q()
{
return Enumerable.Range(0, 100)
.Select(i => i)
.First();
}
发出以下警告:
warning : CodeContracts: requires unproven: Any(source)
如果我删除 .Select()
子句,它就会消失。
但我不清楚我到底需要什么 .Ensure
才能满足 cccheck
。
由于这解决了问题并且仍然不像人们最初想象的那么难看,我将其作为答案发布(如果有人有更好的想法,我愿意接受您的建议):
static public int Q()
{
var e = Enumerable.Range(0, 100)
.Select(i => i);
Contract.Assume(e.Any());
return e.First();
}
所以我不必拆分整个表达式,而是拆分静态分析器害怕的部分,对于那部分我可以保证它是 "all fine, trust me, I know what I'm doing"。
备注:
出于某种原因
Contract.Assert(e.Count() > 0);
或
Contract.Assert(e.Any());
工作。
重要:正如其他人提到的,这可能并不适合所有情况,因为额外的 e.Any()
调用会具体化集合,这在某些情况(例如:当它是来自第 3 方来源的 LINQ 时)。
你能用这段代码避免警告吗?
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
给定的代码
static public int Q()
{
return Enumerable.Range(0, 100)
.Select(i => i)
.First();
}
发出以下警告:
warning : CodeContracts: requires unproven: Any(source)
如果我删除 .Select()
子句,它就会消失。
但我不清楚我到底需要什么 .Ensure
才能满足 cccheck
。
由于这解决了问题并且仍然不像人们最初想象的那么难看,我将其作为答案发布(如果有人有更好的想法,我愿意接受您的建议):
static public int Q()
{
var e = Enumerable.Range(0, 100)
.Select(i => i);
Contract.Assume(e.Any());
return e.First();
}
所以我不必拆分整个表达式,而是拆分静态分析器害怕的部分,对于那部分我可以保证它是 "all fine, trust me, I know what I'm doing"。
备注:
出于某种原因
Contract.Assert(e.Count() > 0);
或
Contract.Assert(e.Any());
工作。
重要:正如其他人提到的,这可能并不适合所有情况,因为额外的 e.Any()
调用会具体化集合,这在某些情况(例如:当它是来自第 3 方来源的 LINQ 时)。
你能用这段代码避免警告吗?
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