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.


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)
{
}
}


Comments: Post a Comment





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]