开发者

C#:What should be the content of the Dispose method when implementing IDisposable interface

开发者 https://www.devze.com 2023-02-11 16:45 出处:网络
I created a class which implements IDisposable interface and VisualStudio IDE brought the Dispose method for me. I am wondering what code i should write inside the Dispose method so that it will take

I created a class which implements IDisposable interface and VisualStudio IDE brought the Dispose method for me. I am wondering what code i should write inside the Dispose method so that it will take care of my memory management or whatever stuff it should do.

public class ESNVerification : IDisposable 
{ 

  public bool Save(string a,string b)
  {
    //Save the data to table
    return true;
  }

  public void Dispose()
  {
       开发者_如何学编程throw new NotImplementedException();
       // Really what i should do here  ?
  }
}


I recommend Three Simple Rules for how to implement IDisposable; simplified here:

  • Rule 1: Don't do it (unless you need to). There are only two situations when IDisposable does need to be implemented: The class owns an unmanaged resource or The class owns managed (IDisposable) resources.
  • Rule 2: For a class owning managed resources, implement IDisposable (but not a finalizer). This implementation of IDisposable should only call Dispose for each owned resource. The class should not have a finalizer.
  • Rule 3: For a class owning a single unmanaged resource, implement both IDisposable and a finalizer.


Unless you're working with some kind of un-managed resources that need to be cleaned up (which, in this extremely simple case, you're not) then you really have no reason to implement IDisposable.

The first line in the MSDN Description of the IDisposable Interface:

The primary use of this interface is to release unmanaged resources

If you were using un-managed resources, then the Dispose method is where you would ensure that those resources are properly released (the Garbage Collector will take care of all of your managed resources for you).


Maybe you should take a look into these MSDN articles:

  • Implementing a Dispose Method
  • Implementing Finalize and Dispose to Clean Up Unmanaged Resources


The dispose method is there so that you can release any resources that you have allocated that is not simple objects (which are cleaned up by garbage collection). For example

  • streams
  • database connections and/or result sets
  • pointers to unmanaged objects
  • any object you have allocated inside your object that is also implementing IDisposable

should be cleaned up in your Dispose method (probably by calling Dispose on those objects).

If you do not have any such resources, you probably do not need to implement IDisposable. However, you might be implementing another interface which inherits from IDisposable, such as IEnumerator. In that case you can leave the Dispose method empty if you don't have any of the resources mentioned above.


Dispose is meant to release unmanaged resources (i.e. resources that are not automatically taken care of by the garbage collector after use). Common examples are database and file connections. Implementing a Dispose Method provides more explanation and a code example.

That page has an important warning that the Dispose method should be implemented in such a way that multiple calls do not throw an exception. That's because it's used by the garbage collector and it can call the dispose method multiple times.


In 99% of cases, Microsoft's framework is vastly overcomplicated, and the right approach is simple:

  1. If your class has any fields of types that implement IDisposable, and nobody's going to expect to use those objects once you're done with them, you should implement IDisposable, and your disposal method should call Dispose on all such fields.
  2. If your class has no such fields, but you think classes that derive from yours might, or if your class needs to implement an interface like IEnumerator(of T) which requires IDisposable, you should have an overridable Dispose method that does nothing.
  3. The proper semantics for a "dispose" method is for an object to do whatever is necessary to clean up other objects before it is abandoned. If an object doesn't have to clean up other objects, Dispose should harmlessly do nothing. There is never any reason to throw NotImplementedException or NotSupportedException from Dispose.

The key point with implementing IDisposable isn't to clean up any particular kind of "resources", but rather to ensure that if an object changes other entities in the system in a way that needs to be cleaned up sometime, those entities will get cleaned up while the information and impetus necessary to do so still exists. Ideally, this cleanup should happen as soon as possible, but no sooner. If an object contains e.g. nothing but a bunch of arrays of strings, there will be no need for cleanup. A string does not require any cleanup; an array of objects not requiring cleanup does not require any cleanup, and an object holding nothing but other objects which don't require cleanup won't require cleanup either. On the other hand, an action like opening a TCP socket creates a need to ensure a certain cleanup action (closing the socket) will be performed. If an object opens a TCP socket and keeps information about it, the purpose of calling Dispose on that object wouldn't be to destroy the information about the socket (that will be taken care of by the garbage collector) but to ensure that the necessary "close" operation on the TCP stack gets performed.


There are two pretty decent articles on MSDN: Implementing a Dispose Method and Implementing Finalize and Dispose to Clean Up Unmanaged Resources. Having observed that the first one says:

There is no performance benefit in implementing the Dispose method on types that use only managed resources (such as arrays) because they are automatically reclaimed by the garbage collector.

I'd recommend you read both, decide whether you need to implement it, and use the code examples there as a start.


There are only two reasons to implement IDisposable1 and what you do inside the Dispose method depends on which one applies to your situation.

If your class creates object instances that implement IDisposable and cannot dispose of them in the method that creates them, that class will have member variables that reference those instances. That class should also implement IDisposable, and inside it you should call Dispose on each disposable member.

If you're using unmanaged resources directly, your class should implement IDisposable and in its Dispose method you should deal with them as needed. What exactly that means will vary a lot, since there's no standard interface available. This is very unusual - normally you use managed classes that handle those for you, like FileStream or SqlConnection. (In which case, see above.)

1 Unless you're deliberately using IDisposable in a non-standard way. (Though the merits of that are debatable.)


The IDisposable pattern should be used when your class use unmanaged system resources, as handles on files, pointers... To free the memory they use.

If your class doesn't use unmanaged resources, it probably don't need to use this pattern.

If you really needs IDisposable :

public void Dispose()
{
  //Free here your resources

  this.Dispose(true);
  GC.SuppressFinalize(this);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号