12

我有一个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) { /* ... */ }
}

这些变通办法让 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());

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

有没有像原始示例中那样与代码合同和 IEnumerables 一起使用的解决方案?如果没有,那么有人开发了一个很好的模式来解决它吗?

4

1 回答 1

8

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

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

退货

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

所以你的谓词可能只是 return true


Contract.Requires(orderIds != null);
Contract.Requires(Contract.Exists(orderIds,a=>true));
于 2012-07-04T10:35:35.880 回答