首页 文章

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

提问于
浏览
11

我有一个 IEnumerable 参数,必须是非空的 . 如果有一个前提条件,如下面的那个,那么集合将在它期间枚举 . 但是下次我引用时会再次列举它 . (Resharper中的一个"Possible multiple enumeration of 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 .

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

1 回答

  • 7

    使用其中一种设计用于 IEnumerable 的方法,例如Contract.Exists

    确定元素集合中的元素是否存在于函数中 . 当且仅当谓词对集合中类型T的任何元素返回true时返回true .

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


    Contract.Requires(orderIds != null);
    Contract.Requires(Contract.Exists(orderIds,a=>true));
    

相关问题