干IDisposable模式 [英] DRY IDisposable Pattern

查看:143
本文介绍了干IDisposable模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很多我的课的重复下面的代码来实现IDisposable。这似乎违背了DRY(不要重复自己)原则。我可以通过创建一个 AbstractDisposable 基类,避免了一些工作,但似乎不恰当的/如果我需要扩展现有的其他对象(假设这些对象间没有是行不通的ŧ自己支配)。

A lot of my classes repeat the below code to implement IDisposable. This seems to violate the DRY (Don't Repeat Yourself) principle. I could avoid some of the work by creating an AbstractDisposable base class, but that seems inappropriate / wouldn't work if I needed to extend other existing objects (assuming those objects weren't themselves disposable).

另一种选择是使用模板/元语言在那里我可以为每一类指定托管和非托管资源的清单,并有通用的Dispose模式当我建我的项目自动生成 - 。但到目前为止,我还没有与元语言扮演/这似乎是极端的这样一个常见的情形

Another option would be to use a template/meta language where I could specify lists of managed and unmanaged resources for each class and have the generic Dispose Pattern auto generated when I build my project - but so far I've not played with meta languages / this seems extreme for such a common scenario.

public class SomeDisposableClass : IDisposable
{
    IDisposable _something; //a managed resource (unique to this class / here for illustration)

    /* ... loads of code unique to this class ... */

    #region Dispose Pattern
    private bool _disposed = false;

    ~SomeDisposableClass()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Check to see if Dispose has already been called. 
        if (!this._disposed)
        {
            if (disposing)
            {
                // Dispose managed resources.
                if (this._something!=null) this._something.Dispose(); //(unique to this class / here for illustration)
            }
            // Clean up any unmanaged resources
            this._disposed = true;
        }
    }
    #endregion
}



有没有实施适当的Dispose模式不违反DRY原则的好办法?

Is there a good way to implement a suitable Dispose pattern without violating the DRY principle?

推荐答案

我会尽量避免 IDisposable的作为最好的,我可以。现在的问题是,它传播整个代码库。如果一个类有一个一次性的成员,这个类必须实现IDisposable,也等。

I try to avoid IDisposable as best as I can. The problem is that it spreads throughout your code base. If a class has a disposable member, that class needs to implement IDisposable, too, etc.

此外,的IDisposable 有问题,当我们谈论类型层次。结果
的一种常见情况是要坚持的IDisposable 到一个基类,甚至一个接口,如果你想得出类需要释放资源。然而,大部分的时间,这只是一种假设,如果需要与否资源清理,使得接口漏水抽象它实际上取决于实际的执行情况。结果
倒不如只实现接口如果真的类需要它的结果
但是这种带有其自身的问题:结果
如何应该有一定界面的消费者知道具体的情况下,他得到了 - 例如为构造函数的参数 - 需要进行处理?他必须显式地检查它。他将基本上必须为每个非密封型,他被交给的每一个实例,做到这一点。

Furthermore, IDisposable has problems when we are talking about type hierarchies.
A common scenario is to stick IDisposable onto a base class or even an interface if you think the derived classes need to free resources. However, most of the times, that's only an assumption and it really depends on the actual implementation if resource cleanup is needed or not, making the interface a leaky abstraction.
It would be better to only implement the interface if the class really needs it.
But this comes with its own problems:
How is the consumer of a certain interface supposed to know that the concrete instance he got - for example as a constructor parameter - needs to be disposed? He would have to explicitly check for it. And he would basically have to do this for every single instance of every non-sealed type he gets handed.

这只是两个例子显示,你是最好的关闭以设计你的类的方式,使他们不需要的IDisposable 的实施。

These are just two examples that show that you are best off to design your classes in a way so that they don't require the implementation of IDisposable.

不过,如果你真的需要实现这个接口,您应该遵循一次性设计模式通过的这个CodeProject上的文章

However, if you really need to implement this interface, you should follow the Disposable Design Pattern as described by this CodeProject article.

它基本上将您的类型分为两个层次:

It basically divides your types into two levels:


  • 0级:0级的类仅包含非托管资源,没有管理的。这些类最需要的通常默认的的IDisposable 模式,虽然你没有实现处理管理资源的一部分。

  • 1级:1级课程只包含管理资源,无论是级别0和1的这些类只需要一个简单的执行的IDisposable ,因为它们不包含非托管资源。实施基本上只是调用的Dispose 在它的每一个0级和1级的成员,并在其基类。

  • Level 0: Classes of level 0 contain only unmanaged resources, no managed ones. These classes need most of the usual default IDisposable pattern, although you don't have to implement the part that handles managed resources.
  • Level 1: Classes of level 1 contain only managed resources, both of Level 0 and 1. These classes only need a simplified implementation of IDisposable because they don't contain unmanaged resources. The implementation basically just calls Dispose on each of its Level 0 and Level 1 members and on its base class.

这篇关于干IDisposable模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆