实现Dispose模式时,对象的属性应在对象被处理后抛出ObjectDisposedException。
如果每个属性和方法在setter的开头有一行代码并且getter抛出该异常,即使它只是ThrowIfDisposed(),它看起来像很多重复的代码。如果您有40个属性,那么80条重复的行。在大型课程中,它可以非常快速地加起来。
我还没有找到更好的方式,所以它看起来就是这样,但我想我会问。还有更好的方法吗?
答案 0 :(得分:7)
如果你在一个类中有40个属性,那么你可能有一个设计问题,但继续...这实际上取决于具体的用例,但是如果该属性实际上不能实际上你应该抛出ObjectDisposedException因为班级已被处理而得到解决。举一个具体的例子:
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之类的库来允许您在编译时注入行为。使用它,您可以根据需要创建应用于属性的属性[ThrowIfDisposed]
。
答案 1 :(得分:0)
检查其他主题:Handling ObjectDisposedException correctly in an IDisposable class hierarchy
每次有人访问实现:IDisposable
的类的属性时,都不需要抛出异常。只有在访问必须处理的对象时才需要(例如,写入/读取文件,访问网络套接字,......)。对于所有其他情况,你可以选择正常的课程。
通常,对象/类没有大量的属性,因为可以选择将它们分成更多的类 - >这将允许您只制作此:IDisposable
的一部分,其余的将独立于IDisposable
类。