我有一个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 一起使用的解决方案?如果没有,那么是否有人开发出一种很好的解决方法?
使用设计用于处理IEnumerable
的方法之一,例如Contract.Exists
:
确定函数中是否存在元素集合中的元素。
返回
true 当且仅当谓词对集合中任何类型 T 的元素返回 true。
所以你的谓词可以只返回true
.
Contract.Requires(orderIds != null);
Contract.Requires(Contract.Exists(orderIds,a=>true));