对IDisposable使用不变量

本文关键字:不变量 IDisposable | 更新日期: 2023-09-27 18:17:31

考虑以下IDisposable类:

class MyClass : IDisposable
{
    public bool IsDisposed { get; private set; } = false;
    public void Dispose()
    {
        IsDisposed = true;
    }
}

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

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

由于在所有方法中都这样写是冗长而重复的,我想使用契约不变量:

public class MyClass : IDisposable
{
    ...
    [ContractInvariantMethod]
    private void objectInvariant()
    {
        Contract.Invariant(!IsDisposed)
    }
    ...
}

然而,这只能确保isdispose在每个公共方法的末尾为false, Dispose()除外。

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

因此对于IDisposable来说,契约不变量是不可用的。还是我错过了什么?

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

对IDisposable使用不变量

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

对象不变量是类的每个实例都应该为真的条件,只要该对象对客户端可见。

(强调我的)在调用Dispose之后,您的对象可以很好地对客户端可见,使对象"无效"。但它实际上是一个有效的状态,为您的对象有IsDisposed == true

你确实在寻找先决条件。