代码契约:要求 IEnumerable 非空

发布于 2024-10-08 09:24:54 字数 978 浏览 1 评论 0原文

我有以下代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

拥醉 2024-10-15 09:24:55

我的意思是,传递一个非空值
已经意味着它至少包含
零元素?

不。相当多返回 IEnumerable 的 API# 实际上总是返回一些东西 - 只是空的。

我该如何检查计数
(或建议的最大值)
IE可枚举?

这实际上才是真正的问题。 Enumerable 没有用于此目的的 API。

I mean, passing a non-null value
already means that it contains atleast
zero elements?

No. Quite some API#s returning an IEnumerable do acutally return something all the time - just empty.

How am I supposed to check the count
(or maximum, as suggested) of an
IEnumerable?

THAT is the real problem actually. An Enumerable has no API for that.

甜是你 2024-10-15 09:24:54

我不确定为什么静态分析建议检查集合的计数。如果传递的是空集合,则计算它的代码将不会执行(即 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 the Count of a collection being a signed type? You may want to try to satisfy the static analyzer with something like Contracts.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 the System.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 an IEnumerable<long>. You still want to check the count, as some methods will throw an exception on an empty IEnumerable (Single<>, for example).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文