Related
the following is a function that invokes the event and thus notifies all clients.
public static void OnEventXYZ(XYZEventArgs e)
{
if(EventXYZ!=null)
EventXYZ(new object(),e);
}
This is from a sample code.
What i want to know is "What is the significance of new object()?
is this a syntax followed or only for this situation?
Normally you pass this as the sender parameter of an event handler.
However, in this case, the event is static so you cannot use this. The person who wrote that sample chose to pass new object() instead. I think most people would pass null instead but that's really a matter of personnal preference.
That parameter is for the sender of the event. Normally, you would use this, but that will not work in the static context.
EventXYZ seems to have been written to expect a sender (typical with event handlers). In the case of the static "On"blahBlah event raiser, the sender isn't really dealt with clearly. As another responder posted, it seems to be an attempt to satisfy the sender property of the event args that are passed along to the handler.
A more correct implementation would likely either omit the sender from the EventArgs or allow the static "OnBlahBlah" method an argument that allows the caller to specify the sender.
The use of "new object()" in this case seems like confusing fluff, IMHO. But, then again, we don't technically know the signature of the constructor being used in this case... perhaps the first argument is meant to be "Some random object that will be used as the thing we can blame later when your hard drive gets formatted".. maybe a new, empty, meaningless object is perfect for this.
Another thing to look for is that you may consider rewriting the code to be this:
public static void OnEventXYZ(XYZEventArgs e)
{
var evt = EventXYZ;
if(evt != null)
evt(new object(),e);
}
.. In a nutshell, that is a typical "sender as first argument" pattern that you see in 99% of event args / event handlers. Better examples will probably make more sense.
You can also use ILSpy or Reflector to look at the thousands of event raisers/handlers in the .NET runtime to get better examples of how the common patterns are coded.
EDIT: BTW, it's unusual to see static OnEvent raisers... it's a little odd. Not technically correct, but it sure messes up the typical "'this' as sender" pattern.
Cheers!
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'm trying to use events to use the nice += -= syntax.
Here is my problem:
I have a lot of different events, so instead of creating many events, I would like to use only one,
where the registrant additionally supplies an additional parameter (string[]) detailing which (sub)events one wants to listen to.
The is basically what I'm doing now:
public delegate void dMethod(int index);
private Dictionary<string, dMethod> events;
public void RegisterEvents(dMethod m, string[] subEvents){
foreach(string subEvent : subEvents){
events[subEvent] += m;
}
}
Instead I would like to do something like this:
public delegate void dMethod(int index);
private Dictionary<string, dMethod> events;
public event dMethod Events(string[] subEvents) {
add {
foreach(string subEvent : subEvents){
events[subEvent] += value;
}
}
remove {
foreach(string subEvent : subEvents){
events[subEvent] -= value;
}
}
}
Is something like passing additional parameters upon event registration somehow possible?
The simplest solution I thought of was to use the delegates return value (changing it to string[]).
But that is just hacky and not worth it.
If it is not possible, is there some way I can define += -= myself?
Why exactly don't you want to use one event per... event ?
What you're trying to do would add an indirection step (which will hurt performance), and more importantly deny you the advantages of compile-time error detection and code analysis (what if your string doesn't match an existing event? wouldn't it be nice to find out about the error at compile-time rather than runtime? What about the "find all references" tool?)
If all of your events are really separate events (which have nothing to do with one another), you should create those events. Creating one single event for all kinds of things would be a bit like creating one big sql table with 255 Columns instead of a true database design.
On the other hand, you may be able to find an abstraction of all those events, and add an argument to the event handler (not to the subscription logic) specifying what sub-event has been called. See IBindingList for an example of this technique. Note the use of an enumeration instead of strings to avoid spelling mistakes.
Could you give us some example (business-wise) of the events you're working on ?
The simplest solution I thought of was
to use the delegates return value
(changing it to string[]).
I dont quite understand what you mean by this. Would the event handler return the events it wants to handle?
I don't think that what you want to do is an option. It may be possible (if you abandon the .Net event system) to use the += syntax by creating a custom class and some implicit conversion operators to produce code something like:
SomePropertyThatIsntARealEvent[new string[] {"event1", "event2"}] += someDelegate
// or even
SomePropertyThatIsntARealEvent["event1"]["event2"] += someDelegate
Note that, if it's even doable, it would be messy and hacky and not really worth it anyways. Also, unfortunately, you can't use params for indexers.
I would recommend that you just stick with the un-pretty way.
This isn't an answer to your main question, but for ease of use I'd add the "params" keyword to your method, like so:
public void RegisterEvents(dMethod m, params string[] subEvents)
This will let you call the method like this:
RegisterEvents(m, "Bob", "Doug", "Susie");
instead of:
RegisterEvents(m, new string[] { "Bob", "Doug", "Susie" });
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.
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.