C# knows two terms, delegate
and event
. Let's start with the first one.
Delegate
A delegate
is a reference to a method. Just like you can create a reference to an instance:
MyClass instance = myFactory.GetInstance();
You can use a delegate to create an reference to a method:
Action myMethod = myFactory.GetInstance;
Now that you have this reference to a method, you can call the method via the reference:
MyClass instance = myMethod();
But why would you? You can also just call myFactory.GetInstance()
directly. In this case you can. But suppose that you don't want to call this method youself, but want to give it other classes to call. Those other classes don't know about the type of myFactory
. In that case, you'll need to let the other classes know about the type of your myFactory
:
TheOtherClass toc;
//...
toc.SetFactory(myFactory);
class TheOtherClass
{
public void SetFactory(MyFactory factory)
{
// set here
}
}
Thanks to delegates, you don't have to expose the type of my factory:
TheOtherClass toc;
//...
Action factoryMethod = myFactory.SetFactory;
toc.SetFactoryMethod(factoryMethod);
class TheOtherClass
{
public void SetFactory(Action factoryMethod)
{
// set here
}
}
Thus, you can give a delegate to some other class to use, without exposing your type to them. The only thing you're exposing is the signature of your method (how many parameters you have and such).
"Signature of my method", where did I hear that before? O yes, interfaces!!! interfaces describe the signature of a whole class. Think of delegates as describing the signature of only one method!
Another large difference between an interface and a delegate, is that when you're writing your class, you don't have to say to C# "this method implements that type of delegate". With interfaces you do need to say "this class implements that type of an interface".
Further, a delegate reference can (with some restrictions) reference multiple methods. An object reference can always only reference to one object.
Event
Events are just properties (like the get;set; properties to instance fields) which expose subscription to the delegate from other objects. These properties, however don't support get;set;. Instead they support add;remove;
So you can have:
Action myField;
public event Action MyProperty
{
add { myField += value; }
remove { myField -= value; }
}
Usage in UI (WinForms)
So, now we know that a delegate is a reference to a method and that we can have an event to let the world know that they can give us their methods to be referenced from our delegate, and we are a UI button, then: we can ask anyone who is interested in whether I was clicked, to register their method with us (via the event we exposed). We can use all those methods that were given to us, and reference them by our delegate. And then, we'll wait and wait.... until a user comes and clicks on that button, then we'll have enough reason to invoke the delegate. And because the delegate references all those methods given to us, all those methods will be invoked. We don't know what those methods do, nor we know which class implements those method. All we do care about is that someone was interested in us being clicked, and gave us a reference to a method that complied with our desired signature.
Heaving said this, languages like Java don't have delegates. They use interfaces instead. The way they do that is to ask anyone who is interested in 'us being clicked', to implement a certain interface (with a certain method we can call), then give us the whole instance that implements the interface. We can that keep a list of all objects implementing this interface, and can call their 'certain method we can call' whenever we get clicked.