There is a LOT of info around about the "standard full" IDisposable implementation for disposing of unmanaged resources - but in reality this case is (very) rare (most resources are already wrapped by managed classes). This question focuses on a mimimal implementation of IDisposable for the much more common "managed resources only" case.
1: Is the mimimal implementation of IDisposable in the code below correct, are there issues?
2: Is there any reason to add a full standard IDisposable implementation (Dispose(), Dispose(bool), Finalizer etc) over the minimal implimentation presented?
3: Is it OK/wise in this minimal case to make the Dispose virtual (since we are not providing Dispose(bool))?
4: If this minimal implementation is replaced with a full standard implementation that includes a (useless, in this case) finalizer - does this change how the GC handles the object? Are there any downsides?
5: The example includes Timer and event handlers as these cases are particularly important not to miss as failing to dispose them will keep objects alive and kicking (this in the case of Timer, eventSource in case of the event handler) until the GC gets round to disposing them in its time. Are there any other examples like these?
class A : IDisposable {
private Timer timer;
public A(MyEventSource eventSource) {
eventSource += Handler
}
private void Handler(object source, EventArgs args) { ... }
public virtual void Dispose() {
timer.Dispose();
if (eventSource != null)
eventSource -= Handler;
}
}
class B : A, IDisposable {
private TcpClient tpcClient;
public override void Dispose() {
(tcpClient as IDispose).Dispose();
base.Dispose();
}
}
refs:
MSDN
SO: When do I need to manage managed resources
SO: How to dispose managed resource in Dispose() method in C#
SO: Dispose() for cleaning up managed resources
The implementation is correct, there are no issues, provided no derived class directly owns an unmanaged resource.
One good reason to implement the full pattern is the "principle of least surprise". Since there is no authoritative document in MSDN describing this simpler pattern, maintenance developers down the line might have their doubts - even you felt the need to ask StackOverflow :)
Yes it's OK for Dispose to be virtual in this case.
The overhead of the unnecessary finalizer is negligible if Dispose has been called, and is correctly implemented (i.e. calls GC.SuppressFinalize)
The overwhelming majority of IDisposable classes outside the .NET Framework itself are IDisposable because they own managed IDisposable resources. It's rare for them to directly hold an unmanaged resource - this only happens when using P/Invoke to access unmanaged resources that aren't exposed by the .NET Framework.
Therefore there is probably a good argument for promoting this simpler pattern:
In the rare cases that unmanaged resources are used, they should be wrapped in a sealed IDisposable wrapper class that implements a finalizer (like SafeHandle). Because it's sealed, this class doesn't need the full IDisposable pattern.
In all other cases, the overwhelming majority, your simpler pattern could be used.
But unless and until Microsoft or some other authoritative source actively promotes it, I'll continue to use the full IDisposable pattern.
Another option is to refactor your code to avoid inheritance and make your IDisposable classes sealed. Then the simpler pattern is easy to justify, as the awkward gyrations to support possible inheritance are no longer necessary. Personally I take this approach most of the time; in the rare case where I want to make a non-sealed class disposable, I just follow the 'standard' pattern. One nice thing about cultivating this approach is that it tends to push you toward composition rather than inheritance, which generally makes code easier to maintain and test.
My recommended Dispose pattern is for a non-virtual Dispose implementation to chain to a virtual void Dispose(bool), preferably after something like:
int _disposed;
public bool Disposed { return _disposed != 0; }
void Dispose()
{
if (System.Threading.Interlocked.Exchange(ref _disposed, 1) != 0)
Dispose(true);
GC.SuppressFinalize(this); // In case our object holds references to *managed* resources
}
Using this approach will ensure that Dispose(bool) only gets called once, even if multiple threads try to invoke it simultaneously. Although such simultaneous disposal attempts are rare(*), it's cheap to guard against them; if the base class doesn't do something like the above, every derived class must have its own redundant double-dispose guard logic and likely a redundant flag as well.
(*) Some communications classes which are mostly single-threaded and use blocking I/O allow Dispose to be called from any threading context to cancel an I/O operation which is blocking its own thread [obviously Dispose can't be called on that thread, since that thread can't do anything while it's blocked]. It's entirely possible--and not unreasonable--for such objects, or objects which encapsulate them, to have an outside thread try to Dispose them as a means of aborting their current operation at just the moment they were going to be disposed by their main thread. Simultaneous Dispose calls are likely to be rare, but their possibility doesn't indicate any "design problem" provided that the Dispose code can act upon one call and ignore the other.
Related
Microsoft design guidelines mention Dispose pattern and scenarios how to use it:
DO implement the Basic Dispose Pattern on types containing instances
of disposable types. See the Basic Dispose Pattern section for details
on the basic pattern.
Later, they show the Basic Dispose Pattern as follows:
public class DisposableResourceHolder : IDisposable {
private SafeHandle resource; // handle to a resource
public DisposableResourceHolder(){
this.resource = ... // allocates the resource
}
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing){
if (disposing){
if (resource!= null) resource.Dispose();
}
}
}
My questions are:
Why do we need to implement Dispose(bool) if it has just a single call with parameter true? It could be easily simplified to just parameterless Dispose() {resource?.Dispose();}. Note we don't need finalizer here because objects we are referencing are managed and have their own finalizers, so they won't be leaked.
Why do they recommend to call GC.SuppressFinalize(this) while not having finalizer? GC anyway wouldn't call finalizer because it does not exist!
The only case when I see the need of Dispose(bool) is when we really have some unmanaged references, which does not implement IDisposable nor finalizer (like shown in this article). But then the meaning of bool disposing would be bool includingManagedResources. So why is it named so misleading 'disposing' to what it should do in fact?
Other classes could inherit from your class. Considering that the deriving class also holds unmanaged resources (recommended or not), this class should then add the finalizer calling Dispose(false). If your class was sealed I would agree with you.
Because the method void Dispose() should not be virtual following the guidelines from Microsoft and thus deriving classes would then have no chance to suppress finalization after disposal. Your implementation might not need a finalizer, but probably deriving classes do.
It's called disposing for no specific reason in my opinion. I personally would rename it as well.
Anyway, from my point of view it is not a good approach to mix owning managed and unmanaged resources. As already mentioned in the comment even Microsoft recommends to encapsulate unmanaged resources into managed ones thus the cases where you need to implement finalizers are probably rare. I cannot remember when I did this myself the last time.
I am also not sticking to the implementation from the guidelines for multiple reasons, like misleading naming or because it's hard to understand. An alternative approach would be this answer.
I am working on a "learning program" and using the Code Rush refactoring tool with my learning. With the latest update of Code Rush it has been recommending implementing IDisposable to my programs. I know what MSDN says about IDisposable and I have a real basic understanding of what it does but because I don't know all the implications of implementing it I have been ignoring the recommendation. Today I decided to learn more about it and went along with the recommendation.
This is what it added to my program.
class Program : IDisposable
{
static Service _proxy;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
if (_proxy != null)
{
_proxy.Dispose();
_proxy = null;
}
}
~Program()
{
Dispose(false);
}
So my questions is this. Does that do everything I need to do to get the advantage of IDisposable or do I need to do something in code to make it work? I put a break points on that and never reached it through the debugger so either it was not needed or I am not using it the way it was intended. Can someone please shed some light on what this is doing for me or how I should use it so it does do something for me?
In this case, CodeRush is suggesting you implement IDisposable because your class encapsulates an IDisposable resource (it's seeing _proxy, though that's not entirely a good thing since it's static). Code Rush thinks that there is a type that you're using which should be explicitly cleaned up, but you're not providing a way to do it via your class.
That being said, IDisposable is tricky - and this is one case where the generated code is not really a good implementation (even if _proxy were an instance variable). I would recommend not using the destructor in this case. It will cause performance issues in the GC, and in this case, doesn't help with the safety, as the encapsulated resource should handle that the case where you forget to call Dispose() for you. For details, see my series on IDisposable, and, in particular, encapsulating an IDisposable class.
In addition, this class shouldn't implement IDisposable (unless there is some other reason to do so) given the code above, as the _proxy resource is static. Disposing a static resource from an instance is likely to cause problems, at least in a general case. (In this case, it's obviously not problematic, but it's not a good practice...) Typically, a static variable has a very different lifetime than an instance member, so automatically disposing of it would be inappropriate.
In a properly-written program, at any given time, for every object that could possibly have a meaningful implementation of IDisposable, there will be some entity that is responsible for ensuring that IDisposable.Dispose will get called on that object sometime between the last "real use" of that instance and its ultimate abandonment. In general, if an object Foo is going to hold references to objects which implement IDisposable, at least one of the following scenarios should apply:
Some other object will also hold the reference for at least as long as Foo needs it, and will take care of calling Dispose on it, so Foo should let the other object take care of the Dispose.
The object holding the reference will be the last thing to use the IDisposable object in question; if Foo doesn't call Dispose, nothing else will. In that scenario, Foo must ensure that that other object's Dispose method gets called once it (Foo) is no longer needed, and before it is abandoned. The most idiomatic way to handle this is for Foo to implement IDisposable.Dispose, and for its Dispose method to call Dispose on the IDisposable objects to which it holds the last useful references.
There are some scenarios where a class designer might not know whether its class is going to hold the last useful reference to an IDisposable object. In some cases, this issue may be resolved by having a class constructor specify whether a IDisposable passed to the constructor is being "lent" or "given". Other cases may require the use of reference-counting wrappers or other complex techniques.
I have been very intriuged by design patterns lately, and specifically following correct design patterns in my classes that implement one or several interfaces.
Let's take an example. When a class implement IDisposable you should follow a specific pattern to make sure that your resources are properly cleaned up, by creating a private Dispose(bool disposing) method that differentiates between if it's called by the finalizer, or if it's called from the public Dispose method. Also, a finalizer should be implemented in this case, and you might also need a private bool variable called isDisposed that is set by the Dispose method, so that any method called after th object is Disposed will call a Exception making it clear that this object is already disposed, instead of the code inside the method crashing because some of the required resouces are disposed, and thereby no longer available.
There are also a lot of other interfaces I routinely implement, but it's not all of them I am sure if the way I implement them is the preferred way of doing it, and I might find out later on that it causes a subtle bug that is hard to find, that would probably have been non-existant if I had followed the proper pattern in the first place.
some examples of interfaces I would like to know the best way of implementing are ISerializable, IComparable, IComparable<>, ICloneable, IEnumerable<>, and so on. All interfaces from the Framework are interesting here, so it should not be limited to those I have listed above.
What I'm after is for different interfaces, the preferred way and hopefully also a link to resource on the internet that explains how and also why a specific pattern should be followed.
I hope to get a good collection of these patterns, as I know that they can greatly improve my code and make it more correct, and follow best-practices
It would be great if there are several patterns for the same interface so we can discuss which one is preferred. That might also cause some of you to maybe move over to a new pattern, or make modifications to your existing patterns to improve your code even further, and that would be great!
Edit
After reading Grzenios comment, I would also urge everyone to give the context the pattern should be applied for. For example the IDIsposable pattern should only be followed if you have some unmanaged resources inside your class that you need to dispose, and not if all the objects you need to dispose implements IDisposable themselves.
Edit 2
I should probably start this myself, since I put the question out here. So I'll describe one pattern I know well, and that is the IDisposable pattern.
This pattern should only be used if your class contain one or more unmanaged resources inside your class, and you hav eto make sure that they get Disposed. in this case in addition to the Dispose method we will need a finalizer in case the user of your class forget to dispose it.
So first thing first. Your class should implement the IDisposable interface, and you will have to define the public Dispose method as goverend by the interface. This method should look like this:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
This will call the protected Dispose(bool) method that takes care of the actual cleanup.
Also, include a vaiable in your class to indicate if the class is disposed or not:
private bool alreadyDisposed = false;
GC.SuppressFinalize tells the garbage collector that this item does not need to be finalized even if it has a finalizer.
Then you need the protected Dispose method. Make it protected instead of private in case any derived class needs to override it:
protected virtual void Dispose(bool isDisposing)
{
if (alreadyDisposed)
{
return;
}
if (isDisposing)
{
// free all managed resources here
}
// free all unmanaged resources here.
alreadyDisposed = true;
}
The finalizer should also call Dispose(bool) if the user forgets to clean up:
~SomeClass(){
Dispose(false);
}
If some method require a disposed resource to function, make the function like this:
public void SomeMethod()
{
if (alreadyDisposed)
throw new ObjectDisposedException("SomeClass",
"Called SomeMethod on Disposed object");
// Method body goes here
}
That's it. This will make sure that the resources gets cleaned up. Preferable by the user of your class calling Dispose, but by adding a Finalizer as a fallback method.
While you're learning about design patterns, you should also look at some common anti-patterns, you get an idea where the pattern comes from. IDisposable is somewhat of an anti-pattern, a minor version of sequential coupling, in that it requires a user to call dispose, and if he forgets, you're in the shit. One of the main reasons of the "disposable pattern" is to fix this issue.
A preferred technique (of mine anyway), wherever possible, is not to expose an IDisposable object to a user, but expose a single method (call it Using(...) for example), which takes a delegate which would execute the code normally contained in your using(...) { } block. This method can perform your construction, execute the delegate, then dispose the resources it consumed, and omits at least 3 problems with IDisposable: That of the user forgetting to call it, the user calling it more than once, and the user calling it too early - you don't need to bother with that boilerplate "disposable pattern" when there's no IDisposable exposed.
An example, lets say I have a File IO requirement where I need to open the same files regularly (and thus, I can't be waiting on the garbage collector to call Finalize in the event that a user forgets to call Dispose).
class MyFileStream {
FileStream fs;
private MyFileStream(string filename, FileMode mode) {
fs = new FileStream(filename, FileMode.Open);
}
private void Dispose() {
fs.Dispose();
}
public static void Using(string filename, FileMode mode, Action<MyFileStream> use) {
MyFileStream mfs = new MyFileStream(filename, mode);
use(mfs);
mfs.Dispose();
}
public void Read(...) { ... }
}
A caller can then say
var x = default(...);
MyFileStream.Using("filename.txt", FileMode.Open, (stream) => {
x = stream.Read(...);
});
Console.WriteLine(x);
Note that this is rather similar to the using() { } language syntax anyway, only this time you are forced to use it, and it imposes further restrictions. One cannot forget to clear up the resources this way.
Still, this pattern isn't always suitable because you sometimes need the resources to last longer than just a method call or so, but if you find the opportunity to use it, do so.
I've completely gone off topic anyway, so back to what you were asking.
Do not use ICloneable - it says nothing about how an object is being cloned (deep or shallow), if you require such thing, create your own IDeepCloneable or IShallowCloneable interfaces instead.
For IEnumerable<>, it's a rare event that you need to create your own, because there's a rather large collection of existing classes in the framework already, and you can usually get additional features much more simply by implementing extension methods (Such as those in LINQ, or your own, making use of the powerful yield keyword, which will create an IEnumerable<> for you in the background).
I wouldn't say there's any specific pattern for the rest, they're pretty self explanatory.
For example the IDIsposable pattern should only be followed if you have some unmanaged resources inside your class that you need to dispose, and not if all the objects you need to dispose implements IDisposable themselves.
I disagee with the above. I never recommend allowing the GC to do clean up and be implicit about object and resource disposal. It's kind of like waiting for the maid to come around and pick up your wet towels at a hotel; it will happen eventually, but the right thing to do is pick them up and hang them up yourself.
Deterministic disposal of objects and keeping scope of those resources as minimal as possible will make for the leanest and most efficient applications, not to mention that for developers reading the code, it is much more explicit to dispose of resources and reads better. Like a beginning and an end to a story that one can see all in one place. I instantiate the object as late as possible and dispose of it as soon as possible after use minimizing scope. Either explicitly calling .Dispose on the object or utilizing a Using block that calls the .Dispose method automatically are (2) good ways of cleaning up.
There are also a lot of other interfaces I routinely implement, but it's not all of them I am sure if the way I implement them is the preferred way of doing it, and I might find out later on that it causes a subtle bug that is hard to find, that would probably have been non-existant if I had followed the proper pattern in the first place.
The entire purpose of an Interface is to create a guidline for the methods, properties, events, etc. that a class is to implement, but not provide the details on how to do it. That is up to you. There is no "pattern" per se of how to implement specefic Interfaces. Don't get thrown off by the IDisposable Interface. Upon creating the Interface in VS.NET, the plumming code is created for you which is not typical for an Interface, and in reality could be completely changed to what you need.
I think where you might be getting confused is about Implementing Interfaces that are in the .NET Framework, but you need to look at the concept of an Interface and not just the ones available in the Framework. If you really want to see examples of how the Interfaces in the .NET Framework are implemented, look at either the MSDN or decompile other Framework objects that implement those Interfaces to see how Microsoft implements them.
As you grow in OOD, you will begin to see the power behind interfaces and begin to create them for your classes. For example lets say you have an interface named IMachine with a method called .StartEngine(). We just want the implementer of the Interface to define all of the details themself; there is no 'pattern' to follow and we the Interface designer don't need to know or care how it is implemented. For a car maybe the methods implementation involves "Get the keys, place them in the ignition, put in park, press brake pedal, turn ignition..." However for a lawnmower the same methods implementation is "Put gass in the mower, prime the carborateor, pull the clutch, pull the cord..."
So you see you can't just look at Interfaces by the ones in the .NET Framework and how to apply a certain pattern to thier implementation. The implementation details, patterns, etc. are up to the implementing class, and as long as the details of the Interface are sufficed, then thats what matters.
Hope this helps a bit...
i've read msdn and various posts about dispose pattern, and there are still a couple of things i don't understand. I've written the following code to test the dispose pattern. Please note that there aren't unmanged resources, i'm using vs2008 and .net 3.5 :
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void tryDispose()
{
//test 1 : allocate resource and leave manage it to gc
BL.myclass df = new BL.myclass();
//test 2 : try to force garbage collecting
//GC.Collect();
//test 3 : call dispose myself
//using (BL.myclass df = new BL.myclass())
//{
//}
}
private void button1_Click(object sender, EventArgs e)
{
tryDispose();
}
this is my disposable class:
class myclass: IDisposable
{
private StronglyTypedDs myDS;
private bool _disposed;
public myclass()
{
using (myDSTableAdapter docDocadpt = new myDSTableAdapter())
{
myDS = new StronglyTypedDs();
docDocadpt.Fill(myDS.TheTable);
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~myclass()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (myDS != null)
myDS .Dispose();
myDS = null;
}
}
_disposed = true;
}
#endregion
}
The results are :
test 1a - just instantiating myclass, the destructor is commentend since myclass doesn't contains unmanaged resources : myclass.dispose is not called, even if i close the application (whose dispose is executed instead) . So what's the state of the dataset once i close the application ?
test 1b - uncommenting destructor, it's ok all disposes are called when i close the application.
test 2a and 2b - i do the above test just calling gc.collect : the behaviour is identical to test 1a and 1b respectively
test 3 - everything works fine (of course)
many posts says that, if myclass doesn't contains unmanaged resources, i don't need to add the destructor; yet in my tests , if i don't add the destructor , myclass.dispose doesn't get called when i close the application. I haven't waited for the gc to run by itself (if i remember correctly gc.collect doesn't guarantes the class instance is deallocated) to check if it will call myclass.dispose .
So what's the correct implemention : always define e destructor or avoid it if myclass contains only managed resources ?
If i had filled all generations levels, would had the gc called myclass dispose or not without having implemented a destructor?
Finally i've noticed that if i define a destructor , but don't declare the class as implementing IDisposable, the disposing chain works anyway. This could make sense since the destructor might be translated to finalize in IL. But i find it really confusing : is it some kind of "implicit" interface implementation i don't know? gc can dispose the item but users can't
thank you in advance
Stefano
Trust your Garbage Collector. Managed resources will get cleaned up, eventually. There is no need for a finalizer or implementing IDisposable unless you have some external resource that needs to be released.
This typically means that you only should implement IDisposable when you either:
Are wrapping a native resource. (In this case, you probably also want a finalizer.)
Are encapsulating a class which implements IDisposable. (In this case, you want IDisposable, but don't need to implement a finalizer/destructor.)
Part of the confusion with IDisposable, in my opinion, is that it covers quite a few use cases, and the proper implementation changes depending on what you're doing (ie: wrapping native resources, wrapping other IDisposable classes, or using Factored types). To address this, I've written a multiple part series on IDisposable - it might help clarify some of this for you.
The correct pattern is to only use a finalizer when your class contains unmanaged resources. As to relying on the GC to dispose of your managed objects, don't. The IDisposable contract makes it clear that this object needs to be disposed.
Ok i think i've understood, referring to my example its correct to implement a dispose because the dataset is global to my class and implements IDisposable , while i don't need the finalizer because there aren't unmanaged resources.
Even if i "forget" to dispose some managed resource in my class dispose method, the gc will collect it at some point. The dispose method is just an utility i provide to other classes/developers for managed resources, a must with the finalizer if i wrap unmanaged resources .
i'll read the articles you have provided asap, but in the mean time i've the last question : when gc will free memory owned by my class and its resources ? when someone calls dispose or when it will run (it will free memory instead of moving it to next generation ) ?
thank you everybody for your answers and examples
I wrote a brief seris entitled How to Implement IDisposable and Finalizers: 3 Easy Rules. It describes a much simpler approach that Microsoft themselves have followed since the 2.0 version of the BCL.
The "official" pattern is needlessly complex and needlessly confusing.
Your code is correct, you've implemented it exactly like it is documented in the MSDN library.
You'll need to take a second look though. Reason what happens when the destructor (aka finalizer) runs. The disposing argument will be false, the protected Dispose method does nothing. This is entirely normal, finalizers should only ever release unmanaged resources. You don't have any. It is extraordinary rare to ever have an unmanaged resource in your own code. They belong in the nice wrapper classes available in .NET to turn an unmanaged operating resource into a nice managed class. If you find yourself thinking you need a finalizer, you'll be wrong 99.99% of the time. Even if you do wrap an unmanaged resource, you should use one of the SafeHandle wrappers. And rely on their finalizers.
Okay, you want to get rid of the destructor. It isn't healthy to leave it in, it keeps the object in memory longer than necessary. When you do, you'll cut it down to:
public void Dispose()
{
if (myDS != null) myDS.Dispose();
}
Which is the boiler-plate implementation of most any Dispose() method, just call the Dispose method of members of the class. You can completely omit it if you don't have any members with a Dispose() method.
Next, you do misunderstand how the Dispose() method gets called. It is not automatic. Which is the point of having it in the first place, releasing resources automatically is already taken care of by the garbage collector. The Dispose() method is there for you to call, either with the using statement or calling it directly. So that you can release the resource early instead of waiting for the garbage collector finalizer thread to get around to it. Which can take a while. Call it when you know that your program won't be using the object anymore.
If your DataSet is actively used by the form then you cannot dispose it until the form closes. Call the class' Dispose() method in a FormClosed event handler. Or, better, open the form's Designer.cs file, cut-and-paste the Dispose() method you find in there and move it to the form's source code file. And add the dispose call. I know that's a bit confuzzling, but the only time it's okay to edit the designer file.
The main purpose of IDisposable is to have a consistent standard interface you can dispose of unmanaged resources with, that is if you didn't do something to ensure Dispose() was called these resources would hang around after the app was closed. Also understood by the using() syntax, that is using will implement the following block for you:
DisposableType someDisposable = new DisposableType();
try
{
// Do whatever
}
finally
{
((IDisposable)someDisposable).Dispose();
}
This is all implemented in a nice design like so:
using(DisposableType someDisposable = new DisposableType())
{
// Do whatever
}
I have the following class
public class Presenter: IDisposable
{
public IView View
{get;private set;}
//snip other object reference, all managed
public Presenter(IView view)
{
View=view;
View.MouseUp += MouseUpEvent;
}
public void MouseUpEvent()
{
//do whatever you want to do on mouse up
}
public void Dispose()
{
View.MouseUp -= MouseUpEvent;
// no more manual disposing
}
}
The question now is, am I implement Dispose() method correctly? Or do I need to manually dispose all the other managed objects just because I have explicilty define Dispose()?
I reckon that the GC is smart enough to do its own disposing ( except the event subscription) even without me manually doing it. Am I right?
If you go with the choice of subscribing in the constructor, then this looks reasonable. I would echo Josh's sentiments that it may not be the best approach. On the other hand, it may be the simplest way of achieving your goal, which is always a good thing. I'm not going to pretend to be an expert on UI patterns: having raised the concern, I'll assume that this is the way you want to work, and address the question itself :)
I personally find Josh's prescribed pattern1 overly complex for simple scenarios - your approach is fine, with just one change: make your class sealed. If you don't want to seal the class, you should go for the Dispose(bool) option (but without the finalizer) because subclasses may also need to dispose of things, and may need a finalizer. Without the possibility of a derived type, life is simpler (as it so often is).
You don't need to do anything with other members just because you now implement IDiposable for that one reason.
So, do you need to derive any further from this class?
1 I do understand that this is the standard recommended pattern, although I'd recommend that you read the advice of Joe Duffy et al for even more details - it can all get very complicated.
Personally, I would avoid hooking/unhooking the event in the constructor and dispose. Instead I would add code to the View get/set accessors and add them there. But if the Presenter is disposed while a View is attached, I would not bother trying to clean that up. You can explicitly detach the View from the presenter if you need explicit detaching.
Having said that, here's what I know about IDisposable.
The recommended approach to implementing IDisposable is to have a protected Dispose(bool) method where you take action. The reason is, you want to distinguish between an explicit disposal and a disposal caused by finalization (garbage collection.)
When you are being disposed because of an explicit Dispose() call, it's ok to touch managed objects and you are expected to dispose of anything you've created that also needs disposing. So you do this only when disposing=true.
But if someone (you) forgets to call Dispose and the finalizer is called, you're being disposed after garbage collection (disposing=false) and you don't want to touch any managed objects because they may already be finalized. The only thing you need to free up in this case is unmanaged resources like Win32 handles and such.
Finally, when Dispose() is explicitly called you'll notice I called GC.SupressFinalize(this) which is a performance hint for the garbage collector. It lets it know that the object doesn't need to be finalized when it is collected. Finalization isn't cheap.
class MyObject : IDisposable {
~MyObject() {
Dispose(false);
}
public void Dispose() {
Dispose(true);
GC.SupressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
// dispose of managed resources
}
// dispose of unmanaged resources
}
}