2015-10-12 18 views
6

Xem xét IDisposable lớp sau:Sử dụng bất biến cho IDisposable

class MyClass : IDisposable 
{ 
    public bool IsDisposed { get; private set; } = false; 

    public void Dispose() 
    { 
     IsDisposed = true; 
    } 
} 

Mỗi phương thức trong lớp này, bao gồm Dispose(), nên bắt đầu với một tấm séc như thế này:

if (IsDisposed) 
{ 
    throw new ObjectDisposedException(...); 
} 

Vì nó là tẻ nhạt và lặp đi lặp lại để viết điều này trong tất cả các phương pháp, tôi muốn sử dụng bất hợp đồng:

public class MyClass : IDisposable 
{ 
    ... 

    [ContractInvariantMethod] 
    private void objectInvariant() 
    { 
     Contract.Invariant(!IsDisposed) 
    } 

    ... 
} 

Tuy nhiên, điều này chỉ đảm bảo IsDisposed là sai ở cuối của mỗi phương thức công khai, ngoại trừ Dispose().

Khi Dispose() được gọi, kiểm tra phải được thực hiện ở đầu mỗi phương thức (bao gồm Dispose()). Nếu không, obejct sẽ ở trạng thái không hợp lệ trong khi chạy phương thức, có khả năng dẫn đến các lỗi khó.

Do đó các bất biến hợp đồng không thực sự có thể sử dụng được cho IDisposable. Hay tôi đang thiếu một cái gì đó?

Có thể buộc các invaraiant cũng được sử dụng như điều kiện tiên quyết hay tôi thực sự phải viết cùng điều kiện tiên quyết (!IsDisposed) cho tất cả các phương thức thủ công?

+4

"Mọi phương thức trong lớp này, bao gồm Dispose(), nên bắt đầu bằng một kiểm tra như thế này" - Phương pháp Vứt bỏ thường có thể được gọi nhiều lần mà không cần ném, vì vậy không nên kiểm tra này. Ngoài ra nó là phổ biến để chỉ làm kiểm tra này trong các thành viên mà không thể được sử dụng sau khi đối tượng được xử lý - các thành viên khác không cần kiểm tra. – Joe

+0

Nhìn vào câu hỏi này quá. tôi nghĩ rằng nó có thể hữu ích. http://stackoverflow.com/questions/9192709/run-a-method-before-all-methods-of-a-class câu hỏi là về làm thế nào để gọi một phương pháp trước khi gọi anymethod trong lớp đó. và có lẽ câu trả lời này http://stackoverflow.com/a/9192747/4767498 –

Trả lời

4

Bạn có vẻ là những bất biến về sự hiểu lầm. Từ tài liệu:

Bất biến đối tượng là điều kiện phải đúng cho từng trường hợp bất cứ khi nào đối tượng đó hiển thị với khách hàng.

(Mỏ nhấn mạnh) Đối tượng của bạn có thể hiển thị rất rõ với khách hàng sau khi bạn gọi là Dispose, khiến đối tượng "không hợp lệ". Nhưng nó thực sự là một trạng thái hợp lệ cho đối tượng của bạn có IsDisposed == true.

Bạn đang thực sự tìm kiếm Điều kiện tiên quyết.

+0

Tôi hiểu. Tôi về cơ bản đang tìm cách tránh đặt cùng điều kiện tiên quyết về cơ bản mọi phương pháp và tài sản đơn lẻ. – Libor

+1

Đó sẽ là một nhiệm vụ cho một thư viện AOP như PostSharp. Bạn cũng có thể tạo ra một interceptor năng động bằng cách sử dụng LinFu. –

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