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,如在原始示例中?如果没有,那么有人制定了一个好的模式来解决它吗?
使用设计用于IEnumerable
s 的方法之一,例如Contract.Exists
:
确定元素集合中的元素是否存在于函数中.
返回
当且仅当谓词对集合中类型T的任何元素返回true时才返回true.
所以你的谓词可以回归true
.
Contract.Requires(orderIds != null);
Contract.Requires(Contract.Exists(orderIds,a=>true));
Run Code Online (Sandbox Code Playgroud)