我有以下代码:
public static IEnumerable<long> GetAllCombinations(IEnumerable<long> elements)
{
Contract.Requires(elements != null);
return GetAllCombinations(elements.ToList(), 0);
}
静态分析现在告诉我添加另一个先决条件:
CodeContracts:建议的前提条件: Contract.Requires(最大值> = 0)
我不明白这个建议,因为
a)如果我已经确保元素不为空,我为什么要检查其计数是大于还是 等于 为零?我的意思是,传递一个非空值已经意味着它包含至少零元素?
b)我应该如何检查IEnumerable的计数(或建议的最大值)?我看到的唯一方法是将elements.ToList()
分配给一个额外的变量并检查该变量。但是,如果我不想从IEnumerable中列出一个列表呢?
让我困惑。
编辑:
我知道IEnumerable<T>
的所有扩展方法,并且非常了解.Any()
,.Count()
等。
让我感到困惑的是来自静态分析仪的信息。任何人都可以解释为什么它陈述Contract.Requires(maximum >= 0)
?
它甚至意味着我认为它意味着什么(检查元素的数量&gt; = 0)?
并且,如评论中所述,为什么静态分析器仍对Contract.Requires(elements.Any());
不满意?
答案 0 :(得分:1)
我不确定为什么静态分析会建议检查集合的数量。如果传递了一个空集合,则不会执行评估它的代码(即foreach
语句),该语句应为o.k.也许这与签名类型的集合的Count
有关?您可能希望尝试使用Contracts.Assume(elements.Any())
或类似非负数的语句来满足静态分析器。
要解决第二个问题,有很多方法可以确定IEnumerable<>
结构是否为非空。列出一些由System.Linq
命名空间启用的内容:
elements.Any()
//检查是否存在至少一个元素O(1)。elements.Count()
//计算所有元素,O(n)elements.Single()
//如果存在多个元素,则引发异常,O(1)。elements.First()
//返回第一个元素,如果为空,则引发异常,O(1)。以下两个变体等同于elements.Any(),其中T是容器中元素的类型:
elements.SingleOrDefault() != default(T)
elements.FirstOrDefault() != default(T)
答案 1 :(得分:0)
elements.Count<long>()
会为您计算IEnumerable<long>
。你仍然想检查计数,因为一些方法会在空IEnumerable(例如Single&lt;&gt;)上抛出异常。
答案 2 :(得分:-1)
我的意思是,传递一个非空值 已经意味着它包含至少 零元素?
没有。相当一些API#s返回一个IEnumerable实际上会一直返回一些东西 - 只是空的。
我该怎么检查计数 (或建议的最大值) IEnumerable的?
实际上这是真正的问题。 Enumerable没有API。