确保IEnumerable不为空的合同

时间:2016-04-14 08:41:35

标签: c# .net static-analysis code-contracts

给定代码

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

发出以下警告:

warning : CodeContracts: requires unproven: Any(source)

如果我删除.Select()条款,它就会消失。

但我不清楚.Ensure到底需要什么才能让cccheck满意。

2 个答案:

答案 0 :(得分:1)

由于这解决了问题并且仍然没有像最初想象的那样难看,我将其作为答案发布(如果有更好的想法,我会打开您的建议):< / p>

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

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

所以我不应该分割整个表达式,而是分析静态分析器所害怕的部分,对于那部分我可以向它保证它一切都很好,相信我,我知道我在做什么&#34;。

注意:

出于某种原因

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

Contract.Assert(e.Any());

的工作。

重要:正如其他人所提到的,这可能不适合所有情况,因为额外的e.Any()调用将实现集合,这在某些情况下可能是不合需要的(例如:当它来自第三方来源的LINQ时。)

答案 1 :(得分: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