对 IDisposable 使用不变量

Using invariant for IDisposable

考虑以下 IDisposable class:

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

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

此 class 中的每个方法,包括 Dispose(),都应以这样的检查开始:

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

由于在所有方法中都这样写是繁琐和重复的,所以我想使用契约不变量:

public class MyClass : IDisposable
{
    ...

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

    ...
}

但是,这只能确保 IsDisposed 在每个 public 方法的末尾 为假 ,不包括 Dispose().

一旦调用了Dispose(),就应该在每个方法(包括Dispose())的开头进行检查。否则对象将在方法 运行 期间处于无效状态,可能导致困难的错误。

因此契约不变量对于 IDisposable 并不是真正可用的。还是我遗漏了什么?

是否可以强制将不变量也用作前提条件,或者我真的必须手动为所有方法编写相同的前提条件 (!IsDisposed) 吗?

您似乎误解了不变量。来自文档:

Object invariants are conditions that should be true for each instance of a class whenever that object is visible to a client.

(强调我的) 在您调用 Dispose 之后,您的对象很可能对客户端可见,使对象成为 "invalid"。但它实际上是您的对象具有 IsDisposed == true.

的有效状态

您真的是在寻找先决条件。