【问题标题】:Collection class and IDisposable interface集合类和 IDisposable 接口
【发布时间】:2015-04-13 13:39:52
【问题描述】:

我最近一直在阅读 IDisposable 接口(这个主题非常有用 Proper use of the IDisposable interface)以及 using 语句的用法(主题 Uses of "using" in C#)。然后我开始想如果我应该以某种方式从内存中释放我自己的集合类会怎样。

class User{
    private string username {set;get;}
    private string password {set;get;}
    ...
}

是否应该实现IDisposable接口?

class User : IDisposable
{
    ...
    public void Dispose()
    {
        this.Dispose();
    }
}

所以它可以从内存中释放出来?还是 GC 会自动执行它,我什至不应该为此烦恼。

据我了解,释放非托管资源(如数据库连接等)很重要,但那些集合类又如何呢?由于我经常使用它们,这真的开始困扰我了。

tl;dr; 我应该在 User 类上实现 IDisposable 吗?

亲切的问候。


编辑:感谢大家的回复!

【问题讨论】:

  • 只有当你的类分配非托管资源和/或有IDisposable类成员时,你才需要实现IDisposable。所以,在你的情况下,答案是“否”,你不需要让这个类一次性。

标签: c# memory garbage-collection dispose idisposable


【解决方案1】:

或者 GC 会自动执行它,我什至不应该打扰它。

这个。除非您有非托管资源(直接或通过引用其他一次性资源),否则您几乎肯定不应该实现 IDisposable

您当前的实现只会调用自己:

public void Dispose()
{
    this.Dispose();
}

...所以假设你真的不想打电话给this.Dispose(),当Dispose() 被调用时你想做什么?这不像处理会导致垃圾收集 - 那么你想采取什么行动?如果答案是“什么都没有”,那么您可能不应该实施IDisposable。 (这里的例外是,如果它被设计为一个基类,并且您期望 一些 派生类需要处理......这是一个更复杂的场景。)

【讨论】:

    【解决方案2】:

    所有未使用的资源最终将在程序卸载时或如果资源不再使用时在单独的时间间隔后被垃圾收集。

    当您不再希望使用资源(变量、对象)来释放内存时,清理/处置使用过的资源(变量、对象)是一种更好的做法。

    【讨论】:

    • 请务必注意,GC 从不调用.Dispose()。你必须自己做。
    【解决方案3】:

    正如其他答案中所说,您必须实施IDisposable 的唯一时间是当您处理非托管资源或IDisposable 本身的类成员时(在这种情况下,您应该处置用你自己的Dispose 方法)。

    您可能会看到的另一种情况是,人们希望使用using { } 语法糖在变量范围末尾自动调用某个方法,而不使用try { } finally { } 形式。

    即:

    public class MyObject : IDisposable
    {
        public void Foo()
        {
        }
    
        public void Dispose()
        {
            // Something they want to call after the use of an instance of MyObject
        }
    }
    ...
    using (var myObj = new MyObject())
    {
        myObj.Foo();
    }
    

    而不是

    public class MyObject
    {
        public void Foo()
        {
        }
    
        public void MethodToCallAfterUse()
        {
            // Something they want to call after the use of an instance of MyObject
        }
    }
    
    var myObj = new MyObject(); 
    try
    {
        myObj.Foo();
    }
    finally
    {
        myObj.MethodToCallAfterUse();
    }
    

    【讨论】:

      【解决方案4】:

      如果一个对象要求外部实体代表它“做某事”(执行操作、保留资源等)直到另行通知,并且在请求其服务的对象停止后该外部实体可能继续存在为了有用,对象应确保外部实体在不再需要其服务时收到通知。 IDisposable 资源作为一种标准方式存在,对象可以通过它说“我可能有义务让外部实体知道何时我不需要他们的服务;让我知道何时不再需要我的服务,这样我就可以履行我告诉任何外部实体我不再需要他们的服务的义务。”

      在 .NET 中,一旦在 Universe 中的任何地方都不存在对某个对象的引用,该对象本身也将不复存在。如果唯一知道有义务执行某些动作的对象在没有执行该动作的情况下不复存在,则该动作将不会被执行。但是,如果一个对象没有义务,那么一旦没有引用就让它不存在就很好了。

      【讨论】:

        猜你喜欢
        • 2012-02-15
        • 1970-01-01
        • 2013-04-08
        • 1970-01-01
        • 2012-05-17
        • 1970-01-01
        • 2013-05-13
        • 2015-12-07
        • 2011-05-07
        相关资源
        最近更新 更多