2012-07-04 36 views
11

Tôi có thông số IEnumerable bắt buộc không trống. Nếu có điều kiện tiên quyết như dưới đây thì bộ sưu tập sẽ được liệt kê trong đó. Nhưng nó sẽ được liệt kê lại lần sau khi tôi tham khảo nó. (A "nhiều liệt kê có thể có của IEnumerable" cảnh báo trong Resharper.)Tổng số đếm liệt kê có thể đếm được do điều kiện tiên quyết hợp đồng

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

    // BAD: collection enumerated again 
    foreach (var i in orderIds) { /* ... */ } 
} 

Những cách giải quyết làm Resharper hạnh phúc nhưng sẽ không biên dịch:

// 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()); 

Có cách giải quyết khác mà có thể có giá trị nhưng có lẽ không luôn luôn lý tưởng như sử dụng ICollection hoặc IList, hoặc thực hiện một điển hình if-null-throw-exception.

Có giải pháp nào hoạt động với hợp đồng mã và IEnumerables như trong ví dụ ban đầu không? Nếu không thì ai đó đã phát triển một mô hình tốt để làm việc xung quanh nó?

+3

Tôi nghĩ rằng nó có thể chỉ là một ý tưởng tồi để có một hợp đồng phụ thuộc vào một IEnumerable - như IEnumerables theo định nghĩa có thể phải chịu tác dụng phụ. –

+0

Cho đến nay tôi đã sử dụng ICollection như một giải pháp thay thế và không bao giờ có vấn đề, mặc dù tôi tò mò nếu có giải pháp cho IEnumerables. – Keith

Trả lời

7

Sử dụng một trong những phương pháp được thiết kế để làm việc với IEnumerable s, như Contract.Exists:

Xác định xem một yếu tố trong một tập hợp các yếu tố tồn tại trong một hàm.

Returns

đúng nếu và chỉ nếu vị trả về true cho bất kỳ yếu tố của loại T trong bộ sưu tập.

Vì vậy, vị từ của bạn chỉ có thể trả lại true.


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

Điều này sẽ không liệt kê 'IEnumerable'? – Rawling

+1

Chỉ khi bạn a) Đã bật Kiểm tra thời gian chạy và b) Chưa chọn "Bỏ qua số lượng". (Mặc dù, trong trường hợp này, tôi khuyên bạn nên tách thành hai 'Yêu cầu') –

+0

Ah OK. Vì vậy, nó sẽ là chính xác để nói rằng không phải là mã ban đầu cũng không mã của bạn _actually_ gây ra một điều tra (modulo a và b của bạn ở trên), nhưng ReSharper không nhận ra điều này trong mã ban đầu, và mã của bạn chỉ cần đặt nó trong một hình thức RS bỏ qua? – Rawling

Các vấn đề liên quan