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?
"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
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 –