2011-08-13 39 views
17

Tôi bắt đầu sử dụng các Hợp đồng Mã, và trong khi Contract.Requires là khá thẳng về phía trước, tôi gặp khó khăn khi nhìn thấy những gì Đảm bảo thực sự làm.Contract.Ensures hoạt động như thế nào?

tôi đã cố gắng tạo ra một phương pháp đơn giản như thế này:

static void Main() 
{ 
    DoSomething(); 
} 

private static void DoSomething() 
{ 
    Contract.Ensures(false, "wrong"); 
    Console.WriteLine("Something"); 
} 

Tôi chưa bao giờ thấy thông báo "sai" Mặc dù vậy, cũng không ném ngoại lệ hoặc bất cứ điều gì khác.

Vì vậy, nó thực sự làm gì?

+1

Tôi bắt đầu bạn ví dụ và có một ngoại lệ chưa được xử lý 'ContractException'" Postcondition không thành công: false wrong "sau khi viết một cái gì đó lên bàn điều khiển. Vì vậy, có vẻ như nó hoạt động tốt. –

+0

Các prover tĩnh là giá trị thực sự đằng sau hợp đồng mã, mặc dù điều này đặc biệt đảm bảo điều kiện là khá kỳ lạ, phân tích nói. Nó tương đương với việc yêu cầu một người chứng minh sự thật của "tuyên bố này là sai." –

+2

Phần sai chỉ là để đảm bảo nó được kích hoạt :-) – Steffen

Trả lời

20

Thật kỳ quặc khi nó không ném bất kỳ thứ gì - nếu bạn đang chạy công cụ ghi đè có cài đặt thích hợp. Tôi đoán là bạn đang chạy trong một chế độ mà không kiểm tra postconditions.

Điều khó hiểu về Contract.Ensures là bạn viết nó vào lúc bắt đầu của phương pháp này, nhưng nó thực hiện ở phần cuối của phương pháp này. Các rewriter hiện tất cả các phép thuật để đảm bảo rằng nó thực hiện một cách thích hợp, và được đưa ra giá trị trả lại nếu cần thiết.

Giống như nhiều điều về Hợp đồng mã, tôi nghĩ tốt nhất nên chạy Reflector trên các kết quả của công cụ viết lại. Hãy chắc chắn rằng bạn đã có các cài đặt đúng, sau đó làm việc ra những gì các rewriter đã làm.


EDIT: Tôi nhận ra tôi đã không bày tỏ điểm của Contact.Ensures được nêu ra. Nói một cách đơn giản, đó là để đảm bảo rằng phương thức của bạn đã làm điều gì đó ở cuối - ví dụ, nó có thể đảm bảo rằng nó được thêm vào danh sách, hoặc (nhiều khả năng hơn) giá trị trả về là không null, hoặc dương hoặc bất cứ thứ gì. Ví dụ, bạn có thể có:

public int IncrementByRandomAmount(int input) 
{ 
    // We can't do anything if we're given int.MaxValue 
    Contract.Requires(input < int.MaxValue); 
    Contract.Ensures(Contract.Result<int>() > input); 

    // Do stuff here to compute output 
    return output; 
} 

Trong đoạn mã viết lại, sẽ có một tấm séc tại điểm lợi nhuận để đảm bảo rằng giá trị trả về thực sự lớn hơn đầu vào.

+0

Bạn đã đúng - chế độ đã được đặt sai trong cài đặt dự án. Sai lầm ngu ngốc về phía tôi :-) – Steffen

+2

@Steffen: Tôi đã thêm một chút nữa để làm cho nó rõ ràng hơn những gì nó có nghĩa là cho. Tôi không biết liệu bạn có cần điều đó hay không, nhưng có lẽ độc giả trong tương lai có thể thấy nó hữu ích :) –

+0

Xây dựng đẹp - đó là khá nhiều những gì tôi mong đợi nó làm, nhưng nó luôn luôn tốt đẹp để có nó bằng văn bản :-) – Steffen

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