|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
About IDisposable.Dispose()I heard from someone that we must not implement IDisposable for all
classes. Can someone please tell me: 1. the reason why we must not implement IDisposable for all the classes we write. 2. what is the correct way of implementing IDisposable.Dispose? 3. what is the preferred way, if there is one over the other, of calling the Dispose method on an object that implements IDisposable. Is it the way that uses the "using(object){}" construct or the way that emphasises on explicitly calling the Dispose method on the object? 1: a better question would be "why should we implement dispose on an
object"? The answer is generally to (either): * release an unmanaged resource in a deterministic fashion * release any disposable managed objects that we own in a class A Dispose method (nor a finalizer) is not the same as a C++ style destructor; it is not really intended as a place to explicitely release managed resources that you own - leave that to the GC. 2: erm, by providing a Dispose() method? If the class has a finalizer (generally *only* for unmanaged wrappers), then this is common: class SomeClass() : IDisposable { public void Dispose() { Dispose(true); } ~SomeClass() { Dispose(false); } protected virtual Dispose(bool disposing) { if(disposing) { // only release *managed* resources if disosing // (else GC may have eaten them already) } // release unmanaged resources } } Note that for best use it should be safe to Dispose() an object multiple times - e.g. in Dipose() ceck if things are null (objects) / 0 (handles); if not, clean them then wipe the field so it doesn't get re-applied if Dispose()d again. 3: "using". It evaluates to the same thing, but you are less likely to get it wrong. And it saves time. Marc For more details:
msdn2: http://msdn2.microsoft.com/en-us/library/system.idisposable.aspx intersting discussion: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=692942&SiteID=1 Water Cooler v2 wrote:
> I heard from someone that we must not implement IDisposable for all It's the same reason you don't implement IEnumerator, IAsyncResult,> classes. Can someone please tell me: > > 1. the reason why we must not implement IDisposable for all the classes > we write. etc. If it's not needed don't bother. Here are few general guidelines that may help determine if it's needed. * DO implement IDisposable if your class directly uses unmanaged resources. For example, a handle obtained from the Win32 API, etc. * DO implement IDisposable if your class indirectly uses unmanaged resources. For example, if your class has a reference to another object that implements IDisposable. * DO override the Finalize method if your class directly uses unmanaged resources. * DON'T override the Finalize method if your class does not directly use managed resource. In other words, don't override Finalize just because your class has a reference to another class that implements IDisposable. * DON'T override the Finalize method in a class who's base class already overrides Finalize. In other words, if the base class provides the protected Dispose(disposing as Boolean) method then you don't need to override Finalize. * DON'T implement IDisposable if your class does not hold unmanaged resources either directly or indirectly. For clarity, I don't consider objects whose scope is limited to methods as being held by the class itself. If a method in your class uses an IDisposable object locally then just make sure it's Dispose method is called before the method ends. > 2. what is the correct way of implementing IDisposable.Dispose? See the MSDN documentation.http://msdn2.microsoft.com/en-us/library/fs2xkftw.aspx Also, consider using the SafeHandle class. > 3. what is the preferred way, if there is one over the other, of Well, I can tell you that I prefer to use the 'using' keyword, but> calling the Dispose method on an object that implements IDisposable. Is > it the way that uses the "using(object){}" construct or the way that > emphasises on explicitly calling the Dispose method on the object? sometimes it just makes more sense to call Dispose explicitly. Great reply and I just want to add that Water Cooler v2 should try to
avoid using finalizers (i.e. ~T()). The class that contains a finalization code should be as small as possible, just wrapper that incapsulate these resources. If a class implements Finalizer, you have to implement IDisposable to give your user a possibility to explicitly clean up the resources. Vladimir. _____________________________ http://cogitosoft.blogspot.com/ http://landvp.com/ Vladimir,
That's an excellent point that I didn't articulate as well as I should have. Implementing IDisposable does not imply that you should override Finalize. But, the converse is true. Brian uladzi***@gmail.com wrote: Show quote > Great reply and I just want to add that Water Cooler v2 should try to > avoid using finalizers (i.e. ~T()). The class that contains a > finalization code should be as small as possible, just wrapper that > incapsulate these resources. > > If a class implements Finalizer, you have to implement IDisposable to > give your user a possibility to explicitly clean up the resources. > > Vladimir. > _____________________________ > http://cogitosoft.blogspot.com/ > http://landvp.com/ Hi,
I'd just like to add that you can get the standardized disposal logic for your classes by deriving from System.ComponentModel.Component, which has the added benefit that your class can be added to designers at design-time, if desired, from the VS.NET toolbox. Another reason one would implement IDisposable on a class is to manage the lifetime of an instance. e.g. TransactionScope. This has the added benefit of supporting the C# "using" statement: using (TransactionScope scope = new TransactionScope()) { // TODO: something transacted } There are classes in the framework that implement IDisposable explicitly and provide a different method such as "Close" instead of "Dispose". Just semantics, but you will see it from time to time. The functionality of these classes is still, commonly, the standardized disposal logic that the other respondents mentioned. -- Show quoteDave Sexton "Water Cooler v2" <wtr_***@yahoo.com> wrote in message news:1157965219.731437.109270@p79g2000cwp.googlegroups.com... >I heard from someone that we must not implement IDisposable for all > classes. Can someone please tell me: > > 1. the reason why we must not implement IDisposable for all the classes > we write. > 2. what is the correct way of implementing IDisposable.Dispose? > 3. what is the preferred way, if there is one over the other, of > calling the Dispose method on an object that implements IDisposable. Is > it the way that uses the "using(object){}" construct or the way that > emphasises on explicitly calling the Dispose method on the object? >
Other interesting topics
|
|||||||||||||||||||||||