处理对象是否处理了所有IDisposable属性?

时间:2014-01-13 18:53:51

标签: c# garbage-collection dispose idisposable

这是一个普遍的问题,虽然我确实有一个我正在研究的特定实例,所以我试图尽可能保持标题和标签的通用性。

我正在与IOC一起做MVC项目。我的具体存储库实现IDisposable来处置Ef上下文。

显然,MVC处理被调用的Controller对象的处理。但是,我是否需要覆盖控制器中的Dispose()?这是我现在的代码:

private IUserRepository repository;

public UserController(IUserRepository repository) {
    this.repository = repository;
}

protected override void Dispose(bool disposing) {
    if (repository is IDisposable && repository != null) {
        (repository as IDisposable).Dispose();
        repository = null;
    }

    base.Dispose(disposing);
}

我检查以确保它实现IDisposable作为单元测试中的模拟我不认为实现它。

现在,我的问题是覆盖Dispose()多余?当Controller(或任何其他对象)被释放时,垃圾收集器是否也会查找实现IDisposable的任何属性,或者我是否正确执行此操作?

3 个答案:

答案 0 :(得分:10)

处置对象不会自动处理IDisposables的所有属性。它只是执行Dispose方法,然后对象所做的就是开发人员。

当处理类的对象时,它应该处置实现IDisposable接口的所有拥有的资源。在你的情况下,你处置一个很可能仍然在使用的对象。

我认为Stephen Cleary关于IDisposable: What Your Mother Never Told You About Resource Deallocation的文章解释了处理对象以及在某些情况下可能出现的困难和问题。

答案 1 :(得分:4)

永远不会自动调用Dispose,甚至垃圾收集器也不会调用。如果对象A控制对象B的生命周期,并且对象B是一次性的,则对象A也应该是一次性的,并且应该手动调用对象B的Dispose方法。

答案 2 :(得分:3)

不,这不是多余的。在任何有一次性成员的班级上实施IDisposable都是你的工作。

您的支票可能是多余的。您应该将模拟配置为允许对存储库对象调用Dispose方法,即使您将其实现为“无所事事”方法进行模拟。

你应该看看Disposable Pattern

它解释了如何以及何时实现IDisposable以及如何链接Destructor和Dispose方法。