对 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
.
的有效状态
您真的是在寻找先决条件。
考虑以下 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
.
您真的是在寻找先决条件。