What are the side-effects of considering Events as instances of Delegates Type?
Jon Skeet says, "Events aren't delegate instances.", here.. I would not have asked this if I had read this anywhere else.
I had always, for the past 2 months, visualized Events as special type of Delegate with the event keyword just helping in preventing the nullification of the Delegate being invoked via the Event.
Could someone please elaborate on how to properly visualize the whole concept for someone new to C# and event based programming?
EDIT 1:
I understood the concepts of delegates and consequently events turned out to be a very simple concept. I would like to go ahead and add an example conjured by me during my battle with these constructs. I have added a lot of comments for better understanding. This is meant for new guys like me:
THE LIBRARY DLL:
namespace DoSomethingLibrary
{
/*
*This is a public delegate declared at the base namespace level for global presence.
*The question is WHY do we need to have a DELEGATE here?
*The answer is: I do not want to implement the LOGGING logic. Why? Well, my consumers are many
*and all are equally demanding. They all need different types of logging. Some need HTML logging,
*some need XML logging for their custom log analyzer, some need plain text logging etc...
*This is hell for me. How am I going to support all their demands. I cannot. Thus, I ask them to
*implement LOGGING on their side. I am providing an INTERFACE(literal sense) in the guise of a DELEGATE.
*A DELEGATE is a HOOK.
*This is the hook that is needed for consumers to hook their custom loggers into the library.
*/
public delegate void Logger(string firstParam, string secondParam);
public class PrintingManiac
{
public Logger printingManiacConsumerLoggerHook;
public void StartPrintingLikeAManiac()
{
for (int iterator = 0; iterator <= 3; iterator++)
{
/*This loop is an emulator which I am using to emulate some huge processing or some huge job.
*Let us imagine that this is a library that does some heavy data crunching OR some
*extremely complex data access job etc..
*/
Console.WriteLine("Actual WORK - " + iterator.ToString());
/*After each step this library tries to LOG. But NOTE that this library
*has no LOGGER implemented. Instead, this library has judiciously DELEGATED
*the logging responsibilty to the CONSUMER of this library.
*/
printingManiacConsumerLoggerHook("Actual Work", "Step " + iterator.ToString());
}
}
}
}
THE CONSUMER EXECUTABLE:
/*
* Let us assume that I have purchased the DoSomethingLibrary DLL from a vendor.
* I have to add the DLL as a reference to my executable's project in Visual Studio.
* I also have to use the DoSomethingLibrary namespace to access the Logic in the DLL.
*/
using DoSomethingLibrary;
namespace UnderstandingDelegates
{
class Program
{
static void Main(string[] args)
{
/*
* Creating an object of the lone class PrintingManiac in the DoSomethingLibrary
*/
PrintingManiac newManiac = new PrintingManiac();
/*
* HOOKING my custom logger to the DoSomethingLibrary DLL.
* I get the best of both the worlds. I have a well-tested and efficient library working for me
* AND I have the best logging avaliable.
* The DoSomethingLibrary DLL has no knowledge of what logging this executable is going to use.
* This executable has to just satisfy the requirements of the DELEGATE signature of DoSomethingLibrary DLL.
*/
newManiac.printingManiacConsumerLoggerHook += new Logger(ClientsCustomizedLoggerTwo);
newManiac.StartPrintingLikeAManiac();
Console.ReadLine();
}
public static void ClientsCustomizedLoggerOne(string firstParam, string secondParam)
{
/*
*This logger has '=' used as a decorator
*In real scenarios the logger may be very complex.
*Let us assume this is an HTML logger
*/
Console.WriteLine("=============================");
Console.WriteLine("Delegated Logging IN CONSUMER code " + firstParam + " - " + secondParam);
Console.WriteLine("=============================");
}
public static void ClientsCustomizedLoggerTwo(string firstParam, string secondParam)
{
/*
*This logger has '-' used as a decorator
*Let us assume this is an XML logger
*/
Console.WriteLine("------------------------------");
Console.WriteLine("Delegated Logging IN CONSUMER code " + firstParam + " - " + secondParam);
Console.WriteLine("------------------------------");
}
}
}
EDIT 2:
I have written an article in CodeProject to clearly explain the whole concept of delegates.
how to properly visualize the whole concept
Nobody ever has much trouble visualizing properties in C#. A property is an accessor to a field, it prevents other code from directly manipulating the field value. Such code is forced to call the get and the set accessors to access the field. You can put arbitrary code in the accessor methods, throwing an exception when you are not happy with the value passed to the setter for example, very common. The underlying storage for the property doesn't have to be a field either, you can expose the field or property of another class object for example. Etcetera.
A good way to visualize an event is to compare it to a property. With the exact same intent, it prevents other code from directly manipulating a delegate object. They have to go through the add and remove accessors. The calls to these methods are generated by syntax sugar in the client code, the += operator calls add(), -= calls remove(). Comparable to the syntax sugar for accessing properties, you don't explicitly write the call to the get or set method either.
What is confusing about events and makes them seem so different from properties is that the event accessor methods are optional. If you don't write them then the C# compiler will auto-generate them for you. Including the backing store, a delegate object. Properties can also have auto-generated accessors and backing store, automatic properties do. But the syntax is different, you still have to declare them.
Using the auto-generated accessors is very common. That code is almost always good enough, it already provides the guarantee that arbitrary code cannot remove the event subscriptions of other code. Not that many good reasons to write your own. One is cutting down on the size of your class object if you support a lot of events. Instead of having a delegate object for each individual event, you can store them in an EventHandlerList instead. Very common in .NET framework code for example. The extra indirection is also taken advantage of in WPF's attached events and WinRT's eventing model with isn't based on delegates.
An event consists of two special methods, called accessors, namely add and remove. Both take in one value parameter value of the same delegate type, and return void.
For example this is an event:
public event Action Exploded
{
add
{
Console.WriteLine("Hello from 'add'. Type of 'value' is '{0}'.", value);
}
remove
{
Console.WriteLine("Hello from 'remove'. Type of 'value' is '{0}'.", value);
}
}
A "field-like" event is a compiler-generated type of event where there is a private generated backing field of the delegate type in question, and where the add accessor adds value to the invocation list of that backing field (delegate combination) whereas the remove accessor removes value from that list. This is done in a smart thread-safe way.
I think one of the biggest sources of confusion regarding events in C# stems from the fact that an event declaration which does not specify explicit add and remove methods creates a delegate with the same name as the event (a design I dislike, btw; VB.NET by default gives the delegate a different name). Thus, declaring an event foo actually declares both an event named foo and a delegate named foo; the name foo will sometimes refer to the delegate and sometimes return to the event.
An event in .NET is really nothing more than a pair of methods, each of which accepts a delegate. One of the methods is called "add", and should cause the method to cause the supplied delegate to be invoked if/when/whenever some particular condition arises. The other method is called "remove", and should ask that a "subscription" associated with a particular delegate be cancelled. Note that nothing about the general event contract requires that an event do anything with a passed-in delegate. An immutable collection could implement an "observable collection" interface but simply ignore any requests to add or remove change notifications [the observable-collection contract would require that all delegates added to the "collection change" event be called when the collection changes, but since there would be no circumstance where the collection could actually change, there would be no circumstance where it would need to call the passed-in delegates].
By default, when a class one declares an event eventName in C#, the compiler also declares a variable eventName of the delegate type associate with the event. Any statements of the form eventName += someDelegate will get translated as eventName_add(someDelegate) and statements of the form eventName -= someDelegate will get translated as eventName_remove(someDelegate). All other references to eventName will be regarded as references to the delegate of that name. Note that in older versions of C#, if the delegate was in scope, statements of the += and -= forms would operate directly on the delegate rather than on the event. This meant that while subscription requests received from outside a class would go through add/remove methods (which would use locking or interlocked methods to provide thread-safety), those processed within a class would not be thread-safe. Later versions of C# always regard eventName += someDelegate and eventName -= someDelegate as add/remove requests, however, even when the delegate is in scope.
Related
I just realized static events exist - and I'm curious how people use them. I wonder how the relative comparison holds up to static vs. instance methods. For instance, a static method is basically a global function. But I've always associated events with instances of objects and I'm having trouble thinking of them at the global level.
Here some code to refer to if it helps an explanation:
void Main()
{
var c1 = new C1();
c1.E1 += () => Console.WriteLine ("E1");
C1.E2 += () => Console.WriteLine ("E2");
c1.F1();
}
// <<delegate>>+D()
public delegate void D();
// +<<event>>E1
// +<<class>><<event>>E2
// +F()
// <<does>>
// <<fire>>E1
// <<fire>>E2
public class C1
{
public void F1()
{
OnE1();
OnE2();
}
public event D E1;
private void OnE1()
{
if(E1 != null)
{
E1();
}
}
static public event D E2;
static private void OnE2()
{
if(E2 != null)
{
E2();
}
}
}
Be wary of static events. Remember that, when an object subscribes to an event, a reference to that object is held by the publisher of the event. That means that you have to be very careful about explicitly unsubscribing from static events as they will keep the subscriber alive forever, i.e., you may end up with the managed equivalent of a memory leak.
Much of OOP can be thought of in terms of message passing.
A method call is a message from the caller to the callee (carrying the parameters) and a message back with the return value.
An event is a message from the source to the subscriber. There are thus potentially two instances involved, the one sending the message and the one receiving it.
With a static event, there is no sending instance (just a type, which may or may not be a class). There still can be a recipient instance encoded as the target of the delegate.
In case you're not familiar with static methods
You're probably already familiar with static methods. In case you're not, An easy-to-understand difference is that you don't need to create an instance of an object toi use a static method, but you DO need to create an instance of an object to call a non-static method.
A good example is the System.IO.Directory and System.IO.DirectoryInfo classes.
The Directory class offers static methods, while the DirectoryInfo class does not.
There are two articles describing them here for you to see the difference for yourself.
http://visualcsharptutorials.com/2011/01/system-io-directory-class/
http://visualcsharptutorials.com/2011/01/system-io-directoryinfo-class/
Now on to static events...
However, static events are seldom seen in the wild. There are very few cases that I can think opf where I'd actually want to use one, but there is a CodeProject article that does show one potential use.
http://www.codeproject.com/KB/cs/staticevent.aspx
The key thought here is taken from the explanation (bold added by me to point out the relevant text):
We saw this property as a separate object and we made sure that there
is only one instance of it at a time. And all instances of
transactions knew where to find it when needed. There is a fine
difference though. The transactions will not need to know about the
changes happening on the exchange rate, rather they will use the last
changed value at the time that they use it by requesting the current
value. This is not enough when, for example, we want to implement an
application where the user interface reacts immediately on changes in
the UI characteristics like font, as if it has to happen at
real-time. It would be very easy if we could have a static property
in the Font class called currentFont and a static method to change
that value and a static event to all instances to let them know when
they need to update their appearance.
As .NET developers we're trained to work with a disconnected model. Think of ADO.NET compared to classic ADO. IN a VB6 app, you could use data controls that would allow the following functionality: If you were running the app on your PC, the data in your grid would update when someone on another PC edited the data.
This isn't something that .NET developers are used to. We're very used to the disconnected model. Static events enable a more "connected" experience. (even if that experience is something we're not used to any more.)
for some insight check this link http://www.codeproject.com/KB/cs/staticevent.aspx
static event can be used
when no instance exists
to do some multicast event for all existing instances...
when you have a static class which can fire events...
BUT one should use them with cuation... see discussion http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/2ac862f346b24a15/8420fbd9294ab12a%238420fbd9294ab12a?sa=X&oi=groupsr&start=1&num=2
more info
http://msdn.microsoft.com/en-us/library/8627sbea.aspx
http://dylanbeattie.blogspot.com/2008/05/firing-static-events-from-instance.html
http://www.nivisec.com/2008/09/static-events-dont-release.html
Static members are not "global," they are simply members of the class, not of class instances. This is as true for events as it is for methods, properties, fields, etc.
I can't give an example for using a static event, because I generally don't find static members to be useful in most cases. (They tend to hint at anti-patterns, like Singleton.)
I have a ugly piece of code that adds event handlers. The problem is, if the code is called multiple times, the event handlers are called multiple times.
To solve the problem, I remove the event handler first and then add it.
Now I've seen the following behaviour:
Some event handlers can be checked like:
if (object.event == null) {
//
// Code
//
}
others of the form
if (object.object.event == null) {
//
// Code
//
}
I get a message like 'object.object.event' may only occur left of -= or +=.
(Since I'm using a german version of visual studio, I don't know the correct translation to english).
I have no idea why the behaviour looks this inconsequent so I would be grateful for some information on this.
To be more specific: It's user control.
if (myControl.Event == null) {
//
// works
//
}
if (myControl.TreeView.NodeMouseClick == null) {
//
// doesn't work
//
}
To solve the problem, I remove the event handler first and then add it.
That doesn't solve the problem. The event keyword provides accessors for a delegate object. Much like a property provides accessors for a field. On a property, you always need one get or set. An event has the add, remove and raise accessors. But the compiler will generate a default implementation for them if you don't do so yourself. Which is fairly common.
The advantage of a property accessor is that the backing field can be private. Nobody can mess with it, except the class that contains the field. All access has to go through the get and set accessors. The event keyword works exactly the same way, nobody can mess with the delegate object, except the code in the class that contains the event.
Which shoots a gaping hole in your attempt to avoid raising the event. You cannot mess with the list of subscribers for an event that's declared in another class, the compiler is telling you this. The normal way this is done is setting a bool flag to indicate that events have to be temporarily ignored. The event handler can check that flag and avoid executing any side-effects.
SLaks is correct, and has linked to some excellent resources. Here's a relevant quote from Chris Burrows' blog article:
Let me take a quick detour here and explain to you how the binding of += works in C#. There are two possibilities:
either there is an actual + operator, such as with ints, and x += y binds to “x = x + y” except that x is only evaluated once. This is the compound assignment operator; or
the thing on the left hand side is an event, and x.E += y binds to “x.add_E(y)”. This is the event accessor operator, and in fact this is the only way to bind to an event accessor.
So what do we have in the snippet above? Well, the extra bit of detail that you need to decide is the following rule about field-like events in C#: outside of the class or struct that defines a field-like event E, binding to the name E resolves to the event itself, on which the only legal operation is calling an accessor; inside the class or struct that defines a field-like event E, binding to the name E resolves to the private delegate field.
In your case, when resolving myControl.Event, you're inside the myControl class, so you don't see an event object; instead you see an actual delegate object, which you can compare with null. When resolving myControl.TreeView.NodeMouseClick, you're outside the TreeView class, so you can't access the actual delegate object; all you get is the event object, which cannot be compared to null.
If I understand correctly, all of this wouldn't help you anyway, since presumably after you check for null, you're going to try to fire the TreeView's event for it, which you can't do.
Depending on what you're trying to do, you could probably subclass TreeView and add an internal method that would call the protected TreeView.OnNodeMouseClick method to fire the event.
You can only access the backing field for an event defined in your class.
For more information, see the spec. (Although this has changed in C# 4, the changes are irrelevant to you)
Best practice in your case would be to create a protected internal OnEventName method in each class.
You can only query your own eventhandlers for attached listeners.
Automatic events, like this one:
public event EventHandler SomethingHappened;
are implemented by the compiler using a multicast delegate.
When you write myControl.Event == null, the compiler actually needs to call Delegate.GetInvocationList on that delegate. The compiler does not let you do that unless the code is inside a method of the class exposing the event, hence the error (it only allows you to add or remove from the invocation list).
If we were talking about an event you define in your own class, then you would have the option of exposing the invocation list (e.g. through a method) and doing what you are trying to do. But for existing classes (e.g. TreeView) it is not possible.
I'm looking to implement the Observer pattern in VB.NET or C# or some other first-class .NET language. I've heard that delegates can be used for this, but can't figure out why they would be preferred over plain old interfaces implemented on observers. So,
Why should I use delegates instead of defining my own interfaces and passing around references to objects implementing them?
Why might I want to avoid using delegates, and go with good ol'-fashioned interfaces?
When you can directly call a method, you don't need a delegate.
A delegate is useful when the code calling the method doesn't know/care what the method it's calling is -- for example, you might invoke a long-running task and pass it a delegate to a callback method that the task can use to send notifications about its status.
Here is a (very silly) code sample:
enum TaskStatus
{
Started,
StillProcessing,
Finished
}
delegate void CallbackDelegate(Task t, TaskStatus status);
class Task
{
public void Start(CallbackDelegate callback)
{
callback(this, TaskStatus.Started);
// calculate PI to 1 billion digits
for (...)
{
callback(this, TaskStatus.StillProcessing);
}
callback(this, TaskStatus.Finished);
}
}
class Program
{
static void Main(string[] args)
{
Task t = new Task();
t.Start(new CallbackDelegate(MyCallbackMethod));
}
static void MyCallbackMethod(Task t, TaskStatus status)
{
Console.WriteLine("The task status is {0}", status);
}
}
As you can see, the Task class doesn't know or care that -- in this case -- the delegate is to a method that prints the status of the task to the console. The method could equally well send the status over a network connection to another computer. Etc.
You're an O/S, and I'm an application. I want to tell you to call one of my methods when you detect something happening. To do that, I pass you a delegate to the method of mine which I want you to call. I don't call that method of mine myself, because I want you to call it when you detect the something. You don't call my method directly because you don't know (at your compile-time) that the method exists (I wasn't even written when you were built); instead, you call whichever method is specified by the delegate which you receive at run-time.
Well technically, you don't have to use delegates (except when using event handlers, then it's required). You can get by without them. Really, they are just another tool in the tool box.
The first thing that comes to mind about using them is Inversion Of Control. Any time you want to control how a function behaves from outside of it, the easiest way to do it is to place a delegate as a parameter, and have it execute the delegate.
You're not thinking like a programmer.
The question is, Why would you call a function directly when you could call a delegate?
A famous aphorism of David Wheeler
goes: All problems in computer science
can be solved by another level of
indirection.
I'm being a bit tongue-in-cheek. Obviously, you will call functions directly most of the time, especially within a module. But delegates are useful when a function needs to be invoked in a context where the containing object is not available (or relevant), such as event callbacks.
There are two places that you could use delegates in the Observer pattern. Since I am not sure which one you are referring to, I will try to answer both.
The first is to use delegates in the subject instead of a list of IObservers. This approach seems a lot cleaner at handling multicasting since you basically have
private delegate void UpdateHandler(string message);
private UpdateHandler Update;
public void Register(IObserver observer)
{
Update+=observer.Update;
}
public void Unregister(IObserver observer)
{
Update-=observer.Update;
}
public void Notify(string message)
{
Update(message);
}
instead of
public Subject()
{
observers = new List<IObserver>();
}
public void Register(IObserver observer)
{
observers.Add(observer);
}
public void Unregister(IObserver observer)
{
observers.Remove(observer);
}
public void Notify(string message)
{
// call update method for every observer
foreach (IObserver observer in observers)
{
observer.Update(message);
}
}
Unless you need to do something special and require a reference to the entire IObserver object, I would think the delegates would be cleaner.
The second case is to use pass delegates instead of IObervers for example
public delegate void UpdateHandler(string message);
private UpdateHandler Update;
public void Register(UpdateHandler observerRoutine)
{
Update+=observerRoutine;
}
public void Unregister(UpdateHandler observerRoutine)
{
Update-=observerRoutine;
}
public void Notify(string message)
{
Update(message);
}
With this, Observers don't need to implement an interface. You could even pass in a lambda expression. This changes in the level of control is pretty much the difference. Whether this is good or bad is up to you.
A delegate is, in effect, passing around a reference to a method, not an object... An Interface is a reference to a subset of the methods implemented by an object...
If, in some component of your application, you need access to more than one method of an object, then define an interface representing that subset of the objects' methods, and assign and implement that interface on all classes you might need to pass to this component... Then pass the instances of these classes by that interface instead of by their concrete class..
If, otoh, in some method, or component, all you need is one of several methods, which can be in any number of different classes, but all have the same signature, then you need to use a delegate.
I'm repeating an answer I gave to this question.
I've always like the Radio Station metaphor.
When a radio station wants to broadcast something, it just sends it out. It doesn't need to know if there is actually anybody out there listening. Your radio is able to register itself with the radio station (by tuning in with the dial), and all radio station broadcasts (events in our little metaphor) are received by the radio who translates them into sound.
Without this registration (or event) mechanism. The radio station would have to contact each and every radio in turn and ask if it wanted the broadcast, if your radio said yes, then send the signal to it directly.
Your code may follow a very similar paradigm, where one class performs an action, but that class may not know, or may not want to know who will care about, or act on that action taking place. So it provides a way for any object to register or unregister itself for notification that the action has taken place.
Delegates are strong typing for function/method interfaces.
If your language takes the position that there should be strong typing, and that it has first-class functions (both of which C# does), then it would be inconsistent to not have delegates.
Consider any method that takes a delegate. If you didn't have a delegate, how would you pass something to it? And how would the the callee have any guarantees about its type?
I've heard some "events evangelists" talk about this and they say that as more decoupled events are, the better it is.
Preferably, the event source should never know about the event listeners and the event listener should never care about who originated the event. This is not how things are today because in the event listener you normally receive the source object of the event.
With this said, delegates are the perfect tool for this job. They allow decoupling between event source and event observer because the event source doesn't need to keep a list of all observer objects. It only keeps a list of "function pointers" (delegates) of the observers.
Because of this, I think this is a great advantage over Interfaces.
Look at it the other way. What advantage would using a custom interface have over using the standard way that is supported by the language in both syntax and library?
Granted, there are cases where it a custom-tailored solution might have advantages, and in such cases you should use it. In all other cases, use the most canonical solution available. It's less work, more intuitive (because it's what users expect), has more support from tools (including the IDE) and chances are, the compiler treats them differently, resulting in more efficient code.
Don't reinvent the wheel (unless the current version is broken).
Actually there was an interesting back-and-forth between Sun and Microsoft about delegates. While Sun made a fairly strong stance against delegates, I feel that Microsoft made an even stronger point for using delegates. Here are the posts:
http://java.sun.com/docs/white/delegates.html
http://msdn.microsoft.com/en-us/vjsharp/bb188664.aspx
I think you'll find these interesting reading...
i think it is more related to syntatic sugar and a way to organize your code, a good use would be to handle several methods related to a common context which ones belong to a object or a static class.
it is not that you are forced to use them, you can programme sth with and without them, but maybe using them or not might affect how organized, readable and why not cool the code would be, maybe bum some lines in your code.
Every example given here is a good one where you could implement them, as someone said it, is just another feature in the language you can play with.
greetings
Here is something that i can write down as a reason of using delegate.
The following code is written in C# And please follow the comments.
public delegate string TestDelegate();
protected void Page_Load(object sender, EventArgs e)
{
TestDelegate TD1 = new TestDelegate(DiaplayMethodD1);
TestDelegate TD2 = new TestDelegate(DiaplayMethodD2);
TD2 = TD1 + TD2; // Make TD2 as multi-cast delegate
lblDisplay.Text = TD1(); // invoke delegate
lblAnotherDisplay.Text = TD2();
// Note: Using a delegate allows the programmer to encapsulate a reference
// to a method inside a delegate object. Its like the function pointer
// in C or C++.
}
//the Signature has to be same.
public string DiaplayMethodD1()
{
//lblDisplay.Text = "Multi-Cast Delegate on EXECUTION"; // Enable on multi-cast
return "This is returned from the first method of delegate explanation";
}
// The Method can be static also
public static string DiaplayMethodD2()
{
return " Extra words from second method";
}
Best Regards,
Pritom Nandy,
Bangladesh
Here is an example that might help.
There is an application that uses a large set of data. A feature is needed that allows the data to be filtered. 6 different filters can be specified.
The immediate thought is to create 6 different methods that each return the data filtered. For example
public Data FilterByAge(int age)
public Data FilterBySize(int size)
.... and so on.
This is fine but is a very limited and produces rubbish code because it's closed for expansion.
A better way is to have a single Filter method and to pass information on how the data should be filtered. This is where a delegate can be used. The delegate is a function that can be applied to the data in order to filter it.
public Data Filter(Action filter)
then the code to use this becomes
Filter(data => data.age > 30);
Filter(data => data.size = 19);
The code data => blah blah becomes a delegate. The code becomes much more flexible and remains open.
I have always wondered how delegates can be useful and why shall we use them? Other then being type safe and all those advantages in Visual Studio Documentation, what are real world uses of delegates.
I already found one and it's very targeted.
using System;
namespace HelloNamespace {
class Greetings{
public static void DisplayEnglish() {
Console.WriteLine("Hello, world!");
}
public static void DisplayItalian() {
Console.WriteLine("Ciao, mondo!");
}
public static void DisplaySpanish() {
Console.WriteLine("Hola, imundo!");
}
}
delegate void delGreeting();
class HelloWorld {
static void Main(string [] args) {
int iChoice=int.Parse(args[0]);
delGreeting [] arrayofGreetings={
new delGreeting(Greetings.DisplayEnglish),
new delGreeting(Greetings.DisplayItalian),
new delGreeting(Greetings.DisplaySpanish)};
arrayofGreetings[iChoice-1]();
}
}
}
But this doesn't show me exactly the advantages of using delegates rather than a conditional "If ... { }" that parses the argument and run the method.
Does anyone know why it's better to use delegate here rather than "if ... { }". Also do you have other examples that demonstrate the usefulness of delegates.
Thanks!
Delegates are a great way of injecting functionality into a method. They greatly help with code reuse because of this.
Think about it, lets say you have a group of related methods that have almost the same functionality but vary on just a few lines of code. You could refactor all of the things these methods have in common into one single method, then you could inject the specialised functionality in via a delegate.
Take for example all of the IEnumerable extension methods used by LINQ. All of them define common functionality but need a delegate passing to them to define how the return data is projected, or how the data is filtered, sorted, etc...
The most common real-world everyday use of delegates that I can think of in C# would be event handling. When you have a button on a WinForm, and you want to do something when the button is clicked, then what you do is you end up registering a delegate function to be called by the button when it is clicked.
All of this happens for you automatically behind the scenes in the code generated by Visual Studio itself, so you might not see where it happens.
A real-world case that might be more useful to you would be if you wanted to make a library that people can use that will read data off an Internet feed, and notify them when the feed has been updated. By using delegates, then programmers who are using your library would be able to have their own code called whenever the feed is updated.
Lambda expressions
Delegates were mostly used in conjunction with events. But dynamic languages showed their much broader use. That's why delegates were underused up until C# 3.0 when we got Lambda expressions. It's very easy to do something using Lambda expressions (that generates a delegate method)
Now imagine you have a IEnumerable of strings. You can easily define a delegate (using Lambda expression or any other way) and apply it to run on every element (like trimming excess spaces for instance). And doing it without using loop statements. Of course your delegates may do even more complex tasks.
I will try to list some examples that are beyond a simple if-else scenario:
Implementing call backs. For example you are parsing an XML document and want a particular function to be called when a particular node is encountered. You can pass delegates to the functions.
Implementing the strategy design pattern. Assign the delegate to the required algorithm/ strategy implementation.
Anonymous delegates in the case where you want some functionality to be executed on a separate thread (and this function does not have anything to send back to the main program).
Event subscription as suggested by others.
Delegates are simply .Net's implementation of first class functions and allow the languages using them to provide Higher Order Functions.
The principle benefit of this sort of style is that common aspects can be abstracted out into a function which does just what it needs to do (for example traversing a data structure) and is provided another function (or functions) that it asks to do something as it goes along.
The canonical functional examples are map and fold which can be changed to do all sorts of things by the provision of some other operation.
If you want to sum a list of T's and have some function add which takes two T's and adds them together then (via partial application) fold add 0 becomes sum. fold multiply 1 would become the product, fold max 0 the maximum. In all these examples the programmer need not think about how to iterate over the input data, need not worry about what to do if the input is empty.
These are simple examples (though they can be surprisingly powerful when combined with others) but consider tree traversal (a more complex task) all of that can be abstracted away behind a treefold function. Writing of the tree fold function can be hard, but once done it can be re-used widely without having to worry about bugs.
This is similar in concept and design to the addition of foreach loop constructs to traditional imperative languages, the idea being that you don't have to write the loop control yourself (since it introduces the chance of off by one errors, increases verbosity that gets in the way of what you are doing to each entry instead showing how you are getting each entry. Higher order functions simply allow you to separate the traversal of a structure from what to do while traversing extensibly within the language itself.
It should be noted that delegates in c# have been largely superseded by lambdas because the compiler can simply treat it as a less verbose delegate if it wants but is also free to pass through the expression the lambda represents to the function it is passed to to allow (often complex) restructuring or re-targeting of the desire into some other domain like database queries via Linq-to-Sql.
A principle benefit of the .net delegate model over c-style function pointers is that they are actually a tuple (two pieces of data) the function to call and the optional object on which the function is to be called. This allows you to pass about functions with state which is even more powerful. Since the compiler can use this to construct classes behind your back(1), instantiate a new instance of this class and place local variables into it thus allowing closures.
(1) it doesn't have to always do this, but for now that is an implementation detail
In your example your greating are the same, so what you actually need is array of strings.
If you like to gain use of delegates in Command pattern, imagine you have:
public static void ShakeHands()
{ ... }
public static void HowAreYou()
{ ... }
public static void FrenchKissing()
{ ... }
You can substitute a method with the same signature, but different actions.
You picked way too simple example, my advice would be - go and find a book C# in Depth.
Here's a real world example. I often use delegates when wrapping some sort of external call. For instance, we have an old app server (that I wish would just go away) which we connect to through .Net remoting. I'll call the app server in a delegate from a 'safecall ' function like this:
private delegate T AppServerDelegate<T>();
private T processAppServerRequest<T>(AppServerDelegate<T> delegate_) {
try{
return delegate_();
}
catch{
//Do a bunch of standard error handling here which will be
//the same for all appserver calls.
}
}
//Wrapped public call to AppServer
public int PostXYZRequest(string requestData1, string requestData2,
int pid, DateTime latestRequestTime){
processAppServerRequest<int>(
delegate {
return _appSvr.PostXYZRequest(
requestData1,
requestData2,
pid,
latestRequestTime);
});
Obviously the error handling is done a bit better than that but you get the rough idea.
Delegates are used to "call" code in other classes (that might not necessarily be in the same, class, or .cs or even the same assembly).
In your example, delegates can simply be replaced by if statements like you pointed out.
However, delegates are pointers to functions that "live" somewhere in the code where for organizational reasons for instance you don't have access to (easily).
Delegates and related syntactic sugar have significantly changed the C# world (2.0+)
Delegates are type-safe function pointers - so you use delegates anywhere you want to invoke/execute a code block at a future point of time.
Broad sections I can think of
Callbacks/Event handlers: do this when EventX happens. Or do this when you are ready with the results from my async method call.
myButton.Click += delegate { Console.WriteLine("Robbery in progress. Call the cops!"); }
LINQ: selection, projection etc. of elements where you want to do something with each element before passing it down the pipeline. e.g. Select all numbers that are even, then return the square of each of those
var list = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
.Where(delegate(int x) { return ((x % 2) == 0); })
.Select(delegate(int x) { return x * x; });
// results in 4, 16, 36, 64, 100
Another use that I find a great boon is if I wish to perform the same operation, pass the same data or trigger the same action in multiple instances of the same object type.
In .NET, delegates are also needed when updating the UI from a background thread. As you can not update controls from thread different from the one that created the controls, you need to invoke the update code withing the creating thread's context (mostly using this.Invoke).
There's a standard pattern for events in .NET - they use a delegate type that takes a plain object called sender and then the actual "payload" in a second parameter, which should be derived from EventArgs.
The rationale for the second parameter being derived from EventArgs seems pretty clear (see the .NET Framework Standard Library Annotated Reference). It is intended to ensure binary compatibility between event sinks and sources as the software evolves. For every event, even if it only has one argument, we derive a custom event arguments class that has a single property containing that argument, so that way we retain the ability to add more properties to the payload in future versions without breaking existing client code. Very important in an ecosystem of independently-developed components.
But I find that the same goes for zero arguments. This means that if I have an event that has no arguments in my first version, and I write:
public event EventHandler Click;
... then I'm doing it wrong. If I change the delegate type in the future to a new class as its payload:
public class ClickEventArgs : EventArgs { ...
... I will break binary compatibility with my clients. The client ends up bound to a specific overload of an internal method add_Click that takes EventHandler, and if I change the delegate type then they can't find that overload, so there's a MissingMethodException.
Okay, so what if I use the handy generic version?
public EventHandler<EventArgs> Click;
No, still wrong, because an EventHandler<ClickEventArgs> is not an EventHandler<EventArgs>.
So to get the benefit of EventArgs, you have to derive from it, rather than using it directly as is. If you don't, you may as well not be using it (it seems to me).
Then there's the first argument, sender. It seems to me like a recipe for unholy coupling. An event firing is essentially a function call. Should the function, generally speaking, have the ability to dig back through the stack and find out who the caller was, and adjust its behaviour accordingly? Should we mandate that interfaces should look like this?
public interface IFoo
{
void Bar(object caller, int actualArg1, ...);
}
After all, the implementor of Bar might want to know who the caller was, so they can query for additional information! I hope you're puking by now. Why should it be any different for events?
So even if I am prepared to take the pain of making a standalone EventArgs-derived class for every event I declare, just to make it worth my while using EventArgs at all, I definitely would prefer to drop the object sender argument.
Visual Studio's autocompletion feature doesn't seem to care what delegate you use for an event - you can type += [hit Space, Return] and it writes a handler method for you that matches whatever delegate it happens to be.
So what value would I lose by deviating from the standard pattern?
As a bonus question, will C#/CLR 4.0 do anything to change this, perhaps via contravariance in delegates? I attempted to investigate this but hit another problem. I originally included this aspect of the question in that other question, but it caused confusion there. And it seems a bit much to split this up into a total of three questions...
Update:
Turns out I was right to wonder about the effects of contravariance on this whole issue!
As noted elsewhere, the new compiler rules leave a hole in the type system that blows up at runtime. The hole has effectively been plugged by defining EventHandler<T> differently to Action<T>.
So for events, to avoid that type hole you should not use Action<T>. That doesn't mean you have to use EventHandler<TEventArgs>; it just means that if you use a generic delegate type, don't pick one that is enabled for contravariance.
Nothing, you lose nothing. I've been using Action<> since .NET 3.5 came out and it is far more natural and easier to program against.
I don't even deal with the EventHandler type for generated event handlers anymore, simply write the method signature you want and wire it up with a lambda:
btnCompleteOrder.OnClick += (o,e) => _presenter.CompleteOrder();
I don't like the event-handler pattern either. To my mind, the Sender object isn't really all that helpful. In cases where an event is saying something happened to some object (e.g. a change notification) it would be more helpful to have the information in the EventArgs. The only use I could kinda-sorta see for Sender would be to unsubscribe from an event, but it's not always clear what event one should unsubscribe to.
Incidentally, if I had my druthers, an Event wouldn't be an AddHandler method and a RemoveHandler method; it would just be an AddHandler method which would return a MethodInvoker that could be used for unsubscription. Rather than a Sender argument, I'd have the first argument be a copy of the MethodInvoker required for unsubscription (in case an object finds itself receiving events to which the unsubscribe invoker has been lost). The standard MulticastDelegate wouldn't be suitable for dispatching events (since each subscriber should receive a different unsubscription delegate) but unsubscribing events wouldn't require a linear search through an invocation list.