在实现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]应用于属性。

09-11 05:04
查看更多