Overview
- Provides an easier way to define events, without having to declare a delegate.
- The EventHandler delegate is used for events without data, while the EventHandler<T> delegate is used with your own EventArgs class.
Good practice
- Implement the IDisposable interface when working with events to prevent memory leaks.
- Read .Net EventHandlers - Best Practices for more information.
- See the example below on how to implement.
- In C# 3.0 it is possible to omit the null check of an event by using the Null Object pattern in the constructor to make sure there is always a listener.
Examples
Event With Custom EventArgs
public class MyEventArgs : EventArgs
{
private string _someData;
public MyEventArgs(string someEventData)
{
this._someData = someEventData;
}
}
public class Program
{
public event EventHandler<MyEventArgs> MyOtherEvent;
public void Test()
{
Program p = new Program();
p.MyOtherEvent += new EventHandler<MyEventArgs>(p_MyOtherEvent);
}
void p_MyOtherEvent(object sender, MyEventArgs e)
{
throw new NotImplementedException();
}
}
Disposing Event Listeners
public class Program
{
static void Main(string[] args)
{
DisposableClass a = new DisposableClass();
// Commenting out the next line will not cause the program to crash,
// because there is always a handler present for SomeEvent. (see constructor)
a.SomeEvent += new EventHandler<MyEventArgs>(a_SomeEvent);
a.SomeMethod();
a.Dispose();
}
static void a_SomeEvent(object sender, MyEventArgs e)
{
Console.WriteLine(e.SomeData);
}
}
public class MyEventArgs : EventArgs
{
private string _someData;
public string SomeData
{
get { return _someData; }
}
public MyEventArgs(string someEventData)
{
this._someData = someEventData;
}
}
public class DisposableClass : IDisposable
{
private bool _disposed = false;
private event EventHandler<MyEventArgs> _someEvent;
public event EventHandler<MyEventArgs> SomeEvent
{
add { _someEvent += value; }
remove { _someEvent -= value; }
}
public DisposableClass()
{
SomeEvent += (s, e) => { };
}
public void SomeMethod()
{
_someEvent(this, new MyEventArgs("Hello"));
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Dispose managed resources.
_someEvent = null;
}
// Release unmanaged resources.
}
_disposed = true;
}
~DisposableClass()
{
Dispose(false);
}
}
You May Also Like

Exam 70-536 Study Notes
My study notes for Microsoft exam 70-536: .NET types, collections, generics, I/O, serialization and more, with C# examples.

Starting Exam 70-536 Study
After a burnout, I'm putting my own project on hold to study for Microsoft exam 70-536.

Design Patterns - Proxy Pattern
The Proxy Pattern, and the last article in the design patterns series, now that I've finished reading Head First Design Patterns.




