可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 ?
}
}
回答1:
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.
回答2:
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).
回答3:
Maybe you should take a look into these MSDN articles:
- Implementing a Dispose Method
- Implementing Finalize and Dispose to Clean Up Unmanaged Resources
回答4:
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.
回答5:
In 99% of cases, Microsoft's framework is vastly overcomplicated, and the right approach is simple:
- 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.
- 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.
- 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.
回答6:
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.
回答7:
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.
回答8:
There are only two reasons to implement IDisposable
1 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.)
回答9:
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);
}