Monday, September 10, 2007
Events vs Delegates
Everyone that has used C# has undoubtably used both delegates and events. And, everyone probably realizes that events use delegates. But, I would be willing to bet that few people actually understand the subtle differences.
Consider the following the following class.
Upon examination, you should realize that the two declarations are basically the same except that the second uses the
In the first declaration,
The
Consider the following the following class.
public class MyClass1
{
public EventHandler MyDelegate;
public event EventHandler MyEvent;
}
Upon examination, you should realize that the two declarations are basically the same except that the second uses the
event keyword in its declaration. But, what does the event keyword really do? To understand why the event keyword is needed when declaring MyEvent, you need to understand the issues that exist with MyDelegate.In the first declaration,
MyDelegate is a public field of delegate type EventHandler. Since this is public, code using MyClass1 can add or remove handlers to the delegate using += and -=. But, that's not all! Code outside of the class can also call any of the delegate methods, reasign the delegate completely or even invoke the delegate itself. This is a big problem! In a publisher-subscriber pattern, this would allow one subscriber to discover and remove other subscribers, or even falsely trigger the delegate.The
event keyword is essentially an access modifier that is designed to prevent that security issue. When a delegate field is declared with the event keyword, code outside of the class can only access the += and -= method of that delegate; none of the other methods of that delegate can be called, and the delegate cannot be cleared or with =.
public class MyClass2
private MyClass1 _myClass1;
public MyClass2(MyClass1 myClass1)
{
_myClass1 = myClass1;
_myClass1.MyDelegate +=
new EventHandler(MyHandlerMethod);
_myClass1.MyEvent +=
new EventHandler(MyHandlerMethod);
Delegate[] invocationList;
// This line is valid
invocationList =
_myClass1.MyDelegate.GetInvocationList();
// This line is *** INVALID ***
invocationList =
_myClass1.MyEvent.GetInvocationList();
}
/// This method would be called
private void MyHandlerMethod(object sender, EventArgs e)
{
}
}
Subscribe to Posts [Atom]