由合同前提条件引起的IEnumerable多枚举

Kei*_*ith 11 .net c# validation ienumerable code-contracts

我有一个IEnumerable非空的参数.如果有一个前提条件,如下面的那个,那么集合将在它期间枚举.但是下次我引用时会再次列举它.(Resharper中的"可能多次枚举IEnumerable"警告.)

void ProcessOrders(IEnumerable<int> orderIds)
{
    Contract.Requires((orderIds != null) && orderIds.Any());  // enumerates the collection

    // BAD: collection enumerated again
    foreach (var i in orderIds) { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

这些变通办法使Resharper高兴但不会编译:

// enumerating before the precondition causes error "Malformed contract. Found Requires 
orderIds = orderIds.ToList();
Contract.Requires((orderIds != null) && orderIds.Any());
---
// enumerating during the precondition causes the same error
Contract.Requires((orderIds != null) && (orderIds = orderIds.ToList()).Any());
Run Code Online (Sandbox Code Playgroud)

还有其他一些有效但可能并不总是理想的解决方法,比如使用ICollection或IList,或执行典型的if-null-throw-exception.

是否有一个解决方案适用于代码契约和IEnumerables,如在原始示例中?如果没有,那么有人制定了一个好的模式来解决它吗?

Dam*_*ver 7

使用设计用于IEnumerables 的方法之一,例如Contract.Exists:

确定元素集合中的元素是否存在于函数中.

返回

当且仅当谓词对集合中类型T的任何元素返回true时才返回true.

所以你的谓词可以回归true.


Contract.Requires(orderIds != null);
Contract.Requires(Contract.Exists(orderIds,a=>true));
Run Code Online (Sandbox Code Playgroud)

  • 这还不会枚举`IEnumerable`吗? (2认同)