代码契约:要求 IEnumerable 非空
我有以下代码:
public static IEnumerable<long> GetAllCombinations(IEnumerable<long> elements)
{
Contract.Requires(elements != null);
return GetAllCombinations(elements.ToList(), 0);
}
静态分析现在告诉我添加另一个前提条件:
CodeContracts:建议的前提条件: Contract.Requires(最大值 >= 0)
我不明白这个建议,因为
a) 如果我已经确保 elements 不为空,为什么我应该检查它的计数是否更大或 等于为零?我的意思是,传递非空值已经意味着它至少包含零个元素?
b) 我应该如何检查 IEnumerable 的计数(或建议的最大值)?我看到的唯一方法是将 elements.ToList() 分配给一个额外的变量并检查该变量。但是,如果我不想从 IEnumerable 中创建一个列表,该怎么办?
让我很困惑。
编辑:
我知道 IEnumerable
的所有扩展方法,并且很清楚 .Any()
、.Count( )
等。
令我困惑的是来自静态分析器的消息。任何人都可以解释为什么它声明 Contract.Requires(maximum >= 0)
吗?
它是否意味着我认为的意思(检查元素计数 >= 0)?
而且,正如评论中提到的,为什么静态分析器仍然对 Contract.Requires(elements.Any());
不满意?
I have the following code:
public static IEnumerable<long> GetAllCombinations(IEnumerable<long> elements)
{
Contract.Requires(elements != null);
return GetAllCombinations(elements.ToList(), 0);
}
Static analysis now tells me to add another precondition:
CodeContracts: Suggested precondition:
Contract.Requires(maximum >= 0)
I don't understand the suggestion because
a) If I already ensure that elements is not null, why should I check if its count is greater or equal to zero? I mean, passing a non-null value already means that it contains atleast zero elements?
b) How am I supposed to check the count (or maximum, as suggested) of an IEnumerable? The only way I see is to assign elements.ToList()
to an extra variable and check that variable. But what, if I don't ever want to make a list out of the IEnumerable?
Leaves me confused.
EDIT:
I know all the extension methods for IEnumerable<T>
and am well aware of .Any()
, .Count()
etc.
What puzzles me is the message from static analyzer. Can anyone explain why it states Contract.Requires(maximum >= 0)
?
Does it even mean what I think it means (checking for count of elements >= 0)?
And, as mentioned in a comment, why is the static analyzer still not happy with Contract.Requires(elements.Any());
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不。相当多返回 IEnumerable 的 API# 实际上总是返回一些东西 - 只是空的。
这实际上才是真正的问题。 Enumerable 没有用于此目的的 API。
No. Quite some API#s returning an IEnumerable do acutally return something all the time - just empty.
THAT is the real problem actually. An Enumerable has no API for that.
我不确定为什么静态分析建议检查集合的计数。如果传递的是空集合,则计算它的代码将不会执行(即
foreach
语句),这应该没问题,也许这与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( ) != 默认(T)
I'm not sure why static analysis suggests checking the count of the collection. If an empty collection is passed, the code that evaluates it will not execute (i.e. a
foreach
statement), which should be o.k. Perhaps this has something to do with theCount
of a collection being a signed type? You may want to try to satisfy the static analyzer with something likeContracts.Assume(elements.Any())
or a statement that states the count is non-negative.To address your second question, there are many ways to determine if an
IEnumerable<>
structure is non-empty. To list a few, enabled by theSystem.Linq
namespace:elements.Any()
// Checks for the presence of at least one element, O(1).elements.Count()
// Counts all the elements, O(n)elements.Single()
// Raises an exception if more than one element exists, O(1).elements.First()
// Returns the first element, or raises an exception if empty, O(1).The following two variations are equivalent to elements.Any(), where T is the type of the element in the container:
elements.SingleOrDefault() != default(T)
elements.FirstOrDefault() != default(T)
elements.Count()
将为您提供IEnumerable
的计数。您仍然需要检查计数,因为某些方法会在空 IEnumerable(例如 Single<>)上引发异常。elements.Count<long>()
will get you the count for anIEnumerable<long>
. You still want to check the count, as some methods will throw an exception on an empty IEnumerable (Single<>, for example).