Should IDisposable be applied cascadingly?

前端 未结 9 1536
灰色年华
灰色年华 2020-12-31 06:48

This is a rather basic question, however I\'m still struggling with it a little.

IDisposable is implemented, when you want to enable the user of an object to free un

相关标签:
9条回答
  • 2020-12-31 07:01

    You should do this, since it's the only way for the user of your class to make sure that the internally held resource is properly disposed.

    However, the pattern used for Dispose() may be slightly different than what is commonly written, in this case, since you don't have to differentiate between unmanaged and managed resources (your encapsulated resource is always treated as a "managed" resource).

    I wrote a detailed blog post on this specific topic - Encapsulating IDisposable Resources.

    0 讨论(0)
  • 2020-12-31 07:01

    There are two distinct scenarios:

    1. Your object is given an object reference to use, either through a constructor argument or a property, and this object implements IDisposable.
    2. Your object constructs an instance of an object that implements IDisposable.

    In the second case, your object is responsible for the resources involved, so your object must implement IDisposable, and when disposed of, you should dispose of the object you constructed.

    Your DbConnection falls under this second case, so yes, your object should implement IDisposable, and then dispose of the connection.

    In the first case, you need to decide on the following three solutions:

    1. Your object is only referencing an external object. Your object should not dispose of this external object. You do not need to implement IDisposable for this case (that is, for this specific object, if you also internally constructs a disposable object, you're back to the second case above).
    2. Your object is taking responsibility for the external object. In this case, you're back to the second case, even though your object was not the one constructing this external object. Here you implement IDisposable, and dispose of the object you're given.
    3. You implement a way for the outside world to tell you which of the first two solutions to pick. For instance, a constructor might be given a connection, and a boolean argument (or ideally an enum value) that tells the constructor whether your object now owns the supplied connection. Here you also need to implement IDisposable, but in the Dispose method, you need to check the ownership and only dispose of the supplied connection if you own it.

    That was a lot of text, so let me summarize:

    1. Objects you own, you need to dispose of.
    2. Objects you don't, you do not dispose.

    There's also a third case, which it doesn't sound like you're having, but nonetheless.

    In the case when you construct, use, and discard, an object locally, inside a single method, without passing it around or storing it in fields of the class, you use the using statement instead, like this:

    using (IDbConnection conn = ....())
    {
    }
    
    0 讨论(0)
  • 2020-12-31 07:03

    It is certainly best practice to do so, especially when working with heavy/unmanaged objects.

    Edit: Best practice, but not mandatory.

    0 讨论(0)
  • 2020-12-31 07:08

    Yes, your class needs to be IDisposable if it needs to dispose of any objects that it uses. An example of this is StreamReader. It implements IDisposable so it can dispose of its associated stream object.

    0 讨论(0)
  • 2020-12-31 07:08

    Of course you can remove a lot of the (re)implementation cost of IDisposable and get something pretty close to deterministic finalization of objects on the managed heap if you use C++/CLI. This is a often (I find) overlooked aspect of a language that a lot of folks seem to consign to the "for glue code only" bin.

    0 讨论(0)
  • 2020-12-31 07:14

    Since we never know when an object is going to be collected by GC we use IDisposable interface to have a chance to intentionally release unmanaged resources before an object is garbage collected. If an disposable object is not dispose before being collected its resources might not been released until the AppDomain is exited. It's almost an unwritten rule that every object that has a reference to an IDisposable object should be IDisposable itself and call Dispose method of its IDisposable references in its own Dispose method.

    0 讨论(0)
提交回复
热议问题