在实现Dispose模式时,对象的属性应在对象被处置后引发ObjectDisposedException。
如果每个属性和方法在setter和getter的开头都有一行代码来抛出该异常,即使它只是ThrowIfDisposed(),也似乎有很多重复的代码。如果您有40个属性,那就是80条重复行。在大类中,它的累加非常快。
我还没有找到更好的方法,所以看起来就是这样,但是我想我会问。有没有更好的办法?
最佳答案
如果在一个类中有40个属性,则可能存在设计问题,但请继续进行……这实际上取决于特定的用例,但是,如果该属性实际上无法解析,则仅应抛出ObjectDisposedException,因为该类(class)已被取消。举一个具体的例子:
public class MyStream : IDisposable
{
private string name;
private Stream stream;
public MyStream(string name)
{
this.Name = name;
this.Stream = new FileStream(...);
}
public string Name
{
get
{
return this.name;
}
}
public Stream Stream
{
get
{
if (this.IsDisposed)
{
throw new ObjectDisposedException();
}
return this.stream;
}
}
private bool IsDisposed { get; set; }
public void Dispose()
{
if (!this.IsDisposed)
{
this.IsDisposed = true;
this.Stream.Dispose();
this.Stream = null;
}
}
}
在这里,属性
Stream
引发异常,因为基础流已被处置,因此无法再使用。但是Name
没有理由抛出。在许多情况下,可以从那里分解代码,以便访问实际有问题的属性会引发异常:
public int Length
{
get
{
// Since we access the Stream property, the ObjectDisposedException
// will be thrown when the class is disposed
return this.Stream.Length;
}
}
如果即使遵循此模式后,仍然有太多无法装饰的属性,则可以使用Fody之类的库,该库可让您在编译时注入(inject)行为。使用它,您可以根据需要将属性
[ThrowIfDisposed]
应用于属性。