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.
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.)
When a class can't (or should not) do something, then events or delegates could be a solution.
say
class President
Event AskedQuestion(QuestionEventArgs)
Delegate GetAnswerToQuestion
class Scientist
AnswerToQuestion()
// delegate approach
myPresident.GetAnswerToQuestion = AddressOf myScientist.AnswerToQuestion
// called once myPresident need it
// event approach
myScientist.AnswerToQuestion(questionEventArgs) Handles President.AskedQuestion
{
// executed once president asked a question
}
Here in the delegate approach Scientist method is used directly by the President class, in the event one President raises a question, and the Scientist react to it with an answer.
In the .NET Framework code I didn't observe, however the direct use of delegates. Is it wrong to use it directly, and if, why?
Is it wrong to use it directly, and if, why?
No, it's not wrong.
Here's how I think about it. Delegate fields are to events as string fields are to properties. That is, you might have:
class Car
{
private string modelName;
public string ModelName { get { return this.modelName; } }
...
The model name is logically a property of a car. When someone asks you what kind of car you drive and you say "a Ford Focus", you are describing a property of the car. You do not think of "Ford Focus" as being a "field" or a "string", you think of it as being the name of a kind of car. In the computer program, the string field is just the implementation detail of how the name is stored. The property could be a string, or it could be an enum, or whatever; the point is that logically, cars have model names, not string fields.
Events and delegates are the same way. A car can have an "explode" event (perhaps you are writing a video game!) and the explode event is implemented by a field of delegate type. Exploding is something the car logically does; the delegate field is the mechanism by which the event is implemented.
So is it "wrong" to use delegates directly? No, of course not. No more than it is "wrong" to use strings directly. Sometimes you need to manipulate strings that are not properties, and sometimes you need to manipulate delegates that are not events.
The trick is to write code that clearly separates the mechanical processes from the business processes. If you find that you're mixing a lot of string logic with your property logic, or mixing a lot of delegate manipulation with your events, then you might consider trying to separate the mechanism code from the business code a bit more, so that it is easier to see which is which.
There is plenty of use of delegates in the framework. LINQ is a clear example of this:
var result = someCollection.Where(input => input.MatchesSomeCriteria);
Where takes a delegate with a specific signature which is invoked in order to determine whether to include an item in the result or not. The most common use is the lamba approach as shown above, but you can just as well pass a method:
string[] nums = new[]{ "1", "2", "3"};
int sum = nums.Select(int.Parse).Sum();
int.Parse matches the required delegate signature that Select expects in this case (Func<string,int>), so it will be invoked for each of the strings in nums.
Typically when delegates are used directly, they are taken as input to method calls that will consume them. There are some places where they are part of the consumers state though (HttpListener for instance has a few properties that are of delegate types), but they are not that many.
working with delegates in the raw can entail some
boilerplate code (defining the delegate, declaring necessary member variables, and creating custom
registration/unregistration methods to preserve encapsulation, etc.).
Typing time aside, another issue with using delegates in the raw as your application’s callback
mechanism is the fact that if you do not define a class’s delegate member variables as private, the
caller will have direct access to the delegate objects. If this were the case, the caller would be able to
reassign the variable to a new delegate object (effectively deleting the current list of functions to
call) and worse yet, the caller would be able to directly invoke the delegate’s invocation list.
events
events are actually one of the things that I really like about .net becuase it lets you declare a much cleaner interface. You can have a president class that announces that it needs an answer without binding it to the implementation of the answering agent like
interface IPresident
{
event Action<QuestionArgs, IPresident> HasQuestion;
void RecieveAnswer(QuestionArgs,Answer);
}
and then in your scientist class
partial class Scientist
{
public Scientist(IPresident president)
{
president.HasQuestion += TryToAnswerQuestion;
}
private void TryToAnswerQuestion(QuestionArgs question, IPresident asker)
{
if(CanAnswerQuestion(question))
{
asker.RecieveAnswer(question,GetAnswer(question));
}
}
}
If a new class wants to answer the presidents questions all they need to do is listen for the event signaling that there is a question that needs to be answered and then answer it if they are able to. If the scientist wants to answer questions from someone else we just need to implement a method that attaches to their Event.
direct delegate invocation
The problem with the delegate approach that you outlined above is that it breaks encapsulation. It tightly couples the scientist and president implementations and makes the code brittle. What happens when you have some other person that answers questions? In your example you are going to need to modify your Scientist implementation in order to add new functionality this is referred to as "brittle" code and is a bad thing. This technique does have some role in composition but it will only rarely, if ever, be the best choice.
the linq case is different, because you aren't exposing a delegate as a member of a class/interface. Instead you are using it as a functor declared by the caller to let you know what information the caller is interested in. Since you are making a "round-trip" encapsulation stays intact.
This lets you define very clean and powerful APIs.
We could take the Scientist example and extend it using this technique to allow someone to find out what questions we can answer like this
partial class Scientist
{
public IEnumerable<QuestionArgs> FindQuestions(Predicate<QuestionArgs> interest, IPresident asker)
{
return this.Questions.Where( x => interest(x) == true && x.IsAuthorizedToAsk(asker))
}
}
// ...
partial class President
{
FirePhysicists()
{
foreach(var scientist in scientists)
{
if(scientist.FindQuestions(x => x.Catagory == QuestionCatagory.Physics, this).Count != 0)
{
scientist.Fire();
}
}
}
}
Note how the FindQuestions method let us not have to implement a bunch of other code to interrogate the scientist that we would have needed without the ability pass delegates around. While this isn't the only case where you are going to find delegates invoked directly it is one of the most common ones
I've read two books, tons of examples. They still make next to no sense to me. I could probably write some code that uses delegates, but I have no idea why. Am I the only one with this problem, or am I just an idiot? If anyone can actually explain to me when, where, and why I would actually use a delegate, I'll love you forever.
Delegates are just a way to pass around a function in a variable.
You pass a delegated function to do a callback. Such as when doing asynchronous IO, you pass a delegated function (a function you have written with the delegate parameter) that will be called when the data has been read off the disk.
As other people have mentioned delegates are handy for callbacks. They're useful for a whole load of other things too. For example in a game I've been working on recently bullets do different things when they hit (some do damage, some actually increase the health of the person they hit, some do no damage but poison the target and so on). The classical OOP way to do this would be a base bullet class and a load of subclasses
Bullet
DamageBullet
HealBullet
PoisonBullet
DoSomethingElseBullet
PoisonAndThenHealBullet
FooAndBarBullet
....
With this pattern, I have to define a new subclass every time I want some new behavior in a bullet, which is a mess and leads to a lot of duplicated code. Instead I solved it with delegates. A bullet has an OnHit delegate, which is called when the bullet hits an object, and of course I can make that delegate anything I like. So now I can create bullets like this
new Bullet(DamageDelegate)
Which obviously is a much nicer way of doing things.
In functional languages, you tend to see a lot more of this kind of thing.
A delegate is a simple container that knows where in the machine's memory a specific method is located.
All delegates have an Invoke(...) method, thus when someone has a delegate, he can actually execute it, without really having to know or bother what that method actually does.
This is especially helpful for decoupling stuff. GUI frameworks wouldn't be possible without that concept, because a Button simply can't know anything about your program you're going to use it in, so it can't call your methods by itself whenever it is clicked. Instead, you must tell it which methods it should call when it is clicked.
I guess you're familiar with events and you do use them regularly. An event field is actually a list of such delegates (also called a multi-cast delegate). Maybe things will become clearer when we look at how we could "simulate" events in C# if it didn't have the event keyword, but only (non-multicast) delegates:
public class Button : Rectangle
{
private List<Delegate> _delegatesToNotifyForClick = new List<Delegate>();
public void PleaseNotifyMeWhenClicked(Delegate d)
{
this._delegatesToNotifyForClick.Add(d);
}
// ...
protected void GuiEngineToldMeSomeoneClickedMouseButtonInsideOfMyRectangle()
{
foreach (Delegate d in this._delegatesToNotifyForClick)
{
d.Invoke(this, this._someArgument);
}
}
}
// Then use that button in your form
public class MyForm : Form
{
public MyForm()
{
Button myButton = new Button();
myButton.PleaseNotifyMeWhenClicked(new Delegate(this.ShowMessage));
}
private void ShowMessage()
{
MessageBox.Show("I know that the button was clicked! :))))");
}
}
Hope I could help a little. ;-)
Maybe this helps:
A delegate is a type (defining a method signature)
A delegate instance is a reference to a method (AKA function pointer)
A callback is a parameter of a delegate-type
An event is a (kind of) property of a delegate-type
The purpose of delegates is that you can have variables/fields/parameters/properties(events) that 'hold' a function. That lets you store/pass a specific function you select runtime. Without it, every function call has to be fixed at compile time.
The syntax involving delegates (or events) can be a bit daunting at first, this has 2 reasons:
simple pointer-to-functions like in C/C++ would not be type-safe, in .NET the compiler actually generates a class around it, and then tries to hide that as much as possible.
delegates are the corner-stone of LINQ, and there is a steep evolution from the specify-everything in C#1 through anonymous methods (C#2) to lambdas (C#3).
Just get acquainted with 1 or 2 standard patterns.
Come on Guys! All of you successfully complicated the DELEGATES :)!
I will try to leave a hint here : i understood delegates once I realized jquery ajax calls in Javascript. for ex: ajax.send(url, data, successcallback, failcallback) is the signature of the function. as you know, it sends data to the server URL, as a response, It might be 200OK or some other error. In case of any such event(success/fail), you want to execute a function. So, this acts like a placeholder of a function, to be able to mention in either success or failure.
That placeholder may not be very generic - it might accept a set of parameters and may/may not return value. That declaration of such Placeholder, if done in C# IS CALLED DELEGATE! As javascript functions not strict with number of arguments, you would just see them as GENERIC placeholders...but C# has some STRICT declarations... that boils down to DELEGATE declarations!!
Hope it helps!
Delegate is a type safe function pointer, meaning delegate points to a function when you invoke the delegate function the actual function will be invoked. It is mainly used when developing core application framework. When we want to decouple logic then we can use delegate. Ie instead of hand coding logic in a particular method we can pass the delegate to the function and set different function logic inside the delegate function. Delegates adds flexibility to your framework.
Example: how to use it
class Program
{
public static void Main()
{
List<Employee> empList = new List<Employee>() {
new Employee () {Name = "Test1", Experience = 6 },
new Employee () {Name = "Test2", Experience = 2 },
};
// delegate point to the actual function
IsPromotable isEligibleToPromote = new IsPromotable(IsEligibleToPromoteEmployee);
Employee emp = new Employee();
// pass the delegate to a method where the delegate will be invoked.
emp.PromoteEmployee(empList, isEligibleToPromote);
// same can be achieved using lambda empression no need to declare delegate
emp.PromoteEmployee(empList, emply => emply.Experience > 2);
Console.ReadKey();
}
// this condition can change at calling end
public static bool IsEligibleToPromoteEmployee(Employee emp)
{
if (emp.Experience > 5)
return true;
else
return false;
}
}
public delegate bool IsPromotable(Employee emp);
public class Employee
{
public string Name { get; set; }
public int Experience { get; set; }
// conditions changes it can 5, 6 years to promote
public void PromoteEmployee(List<Employee> employees, IsPromotable isEligibleToPromote)
{
foreach (var employee in employees)
{
// invoke actual function
if (isEligibleToPromote(employee))
{
Console.WriteLine("Promoted");
}
}
}
}
Is there any different between declaring event Action<> and event EventHandler<>.
Assuming it doesn't matter what object actually raised an event.
for example:
public event Action<bool, int, Blah> DiagnosticsEvent;
vs
public event EventHandler<DiagnosticsArgs> DiagnosticsEvent;
class DiagnosticsArgs : EventArgs
{
public DiagnosticsArgs(bool b, int i, Blah bl)
{...}
...
}
usage would be almost the same in both cases:
obj.DiagnosticsEvent += HandleDiagnosticsEvent;
There are several things that I don’t like about event EventHandler<> pattern:
Extra type declaration derived from
EventArgs
Compulsory passing of object source –
often no one cares
More code means more code to maintain without any clear advantage.
As a result, I prefer event Action<>
However, only if there are too many type arguments in Action<>, then an extra class would be required.
Based on some of the previous answers, I'm going to break my answer down into three areas.
First, physical limitations of using Action<T1, T2, T2... > vs using a derived class of EventArgs. There are three: First, if you change the number or types of parameters, every method that subscribes to will have to be changed to conform to the new pattern. If this is a public facing event that 3rd party assemblies will be using, and there is any possiblity that the event args would change, this would be a reason to use a custom class derived from event args for consistencies sake (remember, you COULD still use an Action<MyCustomClass>) Second, using Action<T1, T2, T2... > will prevent you from passing feedback BACK to the calling method unless you have a some kind of object (with a Handled property for instance) that is passed along with the Action. Third, you don't get named parameters, so if you're passing 3 bool's an int, two string's, and a DateTime, you have no idea what the meaning of those values are. As a side note, you can still have a "Fire this event safely method while still using Action<T1, T2, T2... >".
Secondly, consistency implications. If you have a large system you're already working with, it's nearly always better to follow the way the rest of the system is designed unless you have an very good reason not too. If you have publicly facing events that need to be maintained, the ability to substitute derived classes can be important. Keep that in mind.
Thirdly, real life practice, I personally find that I tend to create a lot of one off events for things like property changes that I need to interact with (Particularly when doing MVVM with view models that interact with each other) or where the event has a single parameter. Most of the time these events take on the form of public event Action<[classtype], bool> [PropertyName]Changed; or public event Action SomethingHappened;. In these cases, there are two benefits. First, I get a type for the issuing class. If MyClass declares and is the only class firing the event, I get an explicit instance of MyClass to work with in the event handler. Secondly, for simple events such as property change events, the meaning of the parameters is obvious and stated in the name of the event handler and I don't have to create a myriad of classes for these kinds of events.
The main difference will be that if you use Action<> your event will not follow the design pattern of virtually any other event in the system, which I would consider a drawback.
One upside with the dominating design pattern (apart from the power of sameness) is that you can extend the EventArgs object with new properties without altering the signature of the event. This would still be possible if you used Action<SomeClassWithProperties>, but I don't really see the point with not using the regular approach in that case.
The advantage of a wordier approach comes when your code is inside a 300,000 line project.
Using the action, as you have, there is no way to tell me what bool, int, and Blah are. If your action passed an object that defined the parameters then ok.
Using an EventHandler that wanted an EventArgs and if you would complete your DiagnosticsArgs example with getters for the properties that commented their purpose then you application would be more understandable. Also, please comment or fully name the arguments in the DiagnosticsArgs constructor.
I realize that this question is over 10 years old, but it appears to me that not only has the most obvious answer not been addressed, but that maybe its not really clear from the question a good understanding of what goes on under the covers. In addition, there are other questions about late binding and what that means with regards to delegates and lambdas (more on that later).
First to address the 800 lb elephant/gorilla in the room, when to choose event vs Action<T>/Func<T>:
Use a lambda to execute one statement or method. Use event when you
want more of a pub/sub model with multiple
statements/lambdas/functions that will execute (this is a major
difference right off the bat).
Use a lambda when you want to compile statements/functions to expression trees. Use delegates/events when you want to participate in more traditional late binding such as used in reflection and COM interop.
As an example of an event, lets wire up a simple and 'standard' set of events using a small console application as follows:
public delegate void FireEvent(int num);
public delegate void FireNiceEvent(object sender, SomeStandardArgs args);
public class SomeStandardArgs : EventArgs
{
public SomeStandardArgs(string id)
{
ID = id;
}
public string ID { get; set; }
}
class Program
{
public static event FireEvent OnFireEvent;
public static event FireNiceEvent OnFireNiceEvent;
static void Main(string[] args)
{
OnFireEvent += SomeSimpleEvent1;
OnFireEvent += SomeSimpleEvent2;
OnFireNiceEvent += SomeStandardEvent1;
OnFireNiceEvent += SomeStandardEvent2;
Console.WriteLine("Firing events.....");
OnFireEvent?.Invoke(3);
OnFireNiceEvent?.Invoke(null, new SomeStandardArgs("Fred"));
//Console.WriteLine($"{HeightSensorTypes.Keyence_IL030}:{(int)HeightSensorTypes.Keyence_IL030}");
Console.ReadLine();
}
private static void SomeSimpleEvent1(int num)
{
Console.WriteLine($"{nameof(SomeSimpleEvent1)}:{num}");
}
private static void SomeSimpleEvent2(int num)
{
Console.WriteLine($"{nameof(SomeSimpleEvent2)}:{num}");
}
private static void SomeStandardEvent1(object sender, SomeStandardArgs args)
{
Console.WriteLine($"{nameof(SomeStandardEvent1)}:{args.ID}");
}
private static void SomeStandardEvent2(object sender, SomeStandardArgs args)
{
Console.WriteLine($"{nameof(SomeStandardEvent2)}:{args.ID}");
}
}
The output will look as follows:
If you did the same with Action<int> or Action<object, SomeStandardArgs>, you would only see SomeSimpleEvent2 and SomeStandardEvent2.
So whats going on inside of event?
If we expand out FireNiceEvent, the compiler is actually generating the following (I have omitted some details with respect to thread synchronization that isn't relevant to this discussion):
private EventHandler<SomeStandardArgs> _OnFireNiceEvent;
public void add_OnFireNiceEvent(EventHandler<SomeStandardArgs> handler)
{
Delegate.Combine(_OnFireNiceEvent, handler);
}
public void remove_OnFireNiceEvent(EventHandler<SomeStandardArgs> handler)
{
Delegate.Remove(_OnFireNiceEvent, handler);
}
public event EventHandler<SomeStandardArgs> OnFireNiceEvent
{
add
{
add_OnFireNiceEvent(value)
}
remove
{
remove_OnFireNiceEvent(value)
}
}
The compiler generates a private delegate variable which is not visible to the class namespace in which it is generated. That delegate is what is used for subscription management and late binding participation, and the public facing interface is the familiar += and -= operators we have all come to know and love : )
You can customize the code for the add/remove handlers by changing the scope of the FireNiceEvent delegate to protected. This now allows developers to add custom hooks to the hooks, such as logging or security hooks. This really makes for some very powerful features that now allows for customized accessibility to subscription based on user roles, etc. Can you do that with lambdas? (Actually you can by custom compiling expression trees, but that's beyond the scope of this response).
To address a couple of points from some of the responses here:
There really is no difference in the 'brittleness' between changing
the args list in Action<T> and changing the properties in a class
derived from EventArgs. Either will not only require a compile
change, they will both change a public interface and will require
versioning. No difference.
With respect to which is an industry standard, that depends on where
this is being used and why. Action<T> and such is often used in IoC
and DI, and event is often used in message routing such as GUI and
MQ type frameworks. Note that I said often, not always.
Delegates have different lifetimes than lambdas. One also has to be
aware of capture... not just with closure, but also with the notion
of 'look what the cat dragged in'. This does affect memory
footprint/lifetime as well as management a.k.a. leaks.
One more thing, something I referenced earlier... the notion of late binding. You will often see this when using framework like LINQ, regarding when a lambda becomes 'live'. That is very different than late binding of a delegate, which can happen more than once (i.e. the lambda is always there, but binding occurs on demand as often as is needed), as opposed to a lambda, which once it occurs, its done -- the magic is gone, and the method(s)/property(ies) will always bind. Something to keep in mind.
On the most part, I'd say follow the pattern. I have deviated from it, but very rarely, and for specific reasons. In the case in point, the biggest issue I'd have is that I'd probably still use an Action<SomeObjectType>, allowing me to add extra properties later, and to use the occasional 2-way property (think Handled, or other feedback-events where the subscriber needs to to set a property on the event object). And once you've started down that line, you might as well use EventHandler<T> for some T.
If you follow the standard event pattern, then you can add an extension method to make the checking of event firing safer/easier. (i.e. the following code adds an extension method called SafeFire() which does the null check, as well as (obviously) copying the event into a separate variable to be safe from the usual null race-condition that can affect events.)
(Although I am in kind of two minds whether you should be using extension methods on null objects...)
public static class EventFirer
{
public static void SafeFire<TEventArgs>(this EventHandler<TEventArgs> theEvent, object obj, TEventArgs theEventArgs)
where TEventArgs : EventArgs
{
if (theEvent != null)
theEvent(obj, theEventArgs);
}
}
class MyEventArgs : EventArgs
{
// Blah, blah, blah...
}
class UseSafeEventFirer
{
event EventHandler<MyEventArgs> MyEvent;
void DemoSafeFire()
{
MyEvent.SafeFire(this, new MyEventArgs());
}
static void Main(string[] args)
{
var x = new UseSafeEventFirer();
Console.WriteLine("Null:");
x.DemoSafeFire();
Console.WriteLine();
x.MyEvent += delegate { Console.WriteLine("Hello, World!"); };
Console.WriteLine("Not null:");
x.DemoSafeFire();
}
}
Looking at Standard .NET event patterns we find
The standard signature for a .NET event delegate is:
void OnEventRaised(object sender, EventArgs args);
[...]
The argument list contains two arguments: the sender, and the event arguments. The compile time type of sender is System.Object, even though you likely know a more derived type that would always be correct. By convention, use object.
Below on same page we find an example of the typical event definition which is something like
public event EventHandler<EventArgs> EventName;
Had we defined
class MyClass
{
public event Action<MyClass, EventArgs> EventName;
}
the handler could have been
void OnEventRaised(MyClass sender, EventArgs args);
where sender has the correct (more derived) type.
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).