2010-06-23 24 views
11

OK, tôi có thêm một câu hỏi về Hợp đồng mã khác. Tôi có một hợp đồng trên một phương pháp giao diện trông giống như thế này (phương pháp khác bỏ qua cho rõ ràng):Sử dụng hợp đồng .ForAll trong các hợp đồng mã số

[ContractClassFor(typeof(IUnboundTagGroup))] 
public abstract class ContractForIUnboundTagGroup : IUnboundTagGroup 
{ 
    public IUnboundTagGroup[] GetAllGroups() 
    { 
     Contract.Ensures(Contract.Result<IUnboundTagGroup[]>() != null); 
     Contract.Ensures(Contract.ForAll(Contract.Result<IUnboundTagGroup[]>(), g => g != null)); 

     return null; 
    } 
} 

tôi có mã tốn nhiều giao diện trông như thế này:

public void AddRequested(IUnboundTagGroup group) 
    { 
      foreach (IUnboundTagGroup subGroup in group.GetAllGroups()) 
      { 
       AddRequested(subGroup); 
      } 
      //Other stuff omitted 
    } 

AddRequested đòi hỏi một phi null tham số đầu vào (nó thực hiện một giao diện trong đó có một hợp đồng Yêu cầu) và vì vậy tôi nhận được một lỗi 'yêu cầu chưa được chứng minh: nhóm! = null' trên nhóm con được chuyển vào AddRequested. Tôi có sử dụng cú pháp ForAll chính xác không? Nếu vậy và người giải quyết đơn giản là không hiểu, có cách nào khác để giúp người giải quyết nhận ra hợp đồng hay tôi chỉ đơn giản là cần sử dụng một Giả sử bất cứ khi nào GetAllGroups() được gọi?

+0

Phiên bản mới nhất đã bật 'ForAll', bạn có thể thử dùng thử :) – porges

Trả lời

9

Trạng thái Code Contracts User Manual, "Trình kiểm tra hợp đồng tĩnh chưa xử lý số liệu ForAll hoặc Exists". Cho đến khi có, có vẻ như với tôi các tùy chọn là:

  1. Bỏ qua cảnh báo.
  2. Thêm Contract.Assume(subGroup != null) trước khi gọi tới AddRequested().
  3. Thêm séc trước khi gọi tới AddRequested(). Có thể if (subGroup == null) throw new InvalidOperationException() hoặc if (subGroup != null) AddRequested(subGroup).

Tùy chọn 1 không thực sự hữu ích. Tùy chọn 2 là nguy hiểm vì nó sẽ phá vỡ hợp đồng Yêu cầu AddRequested() ngay cả khi IUnboundTagGroup.GetAllGroups() không còn đảm bảo rằng điều kiện sau. Tôi muốn đi với tùy chọn 3.

+2

Cảm ơn; Tôi nghĩ rằng tôi có thể sẽ đi với bằng cách sử dụng Assume, kể từ khi mã ban đầu (pre-Contracts) đã không có một kiểm tra null. Nó cũng đánh dấu một cách rõ ràng các nơi khác nhau mà người prover tĩnh cần 'giúp đỡ' để hy vọng tôi có thể quay lại và loại bỏ một số người trong số họ khi người prover trở nên mạnh mẽ hơn. –

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