Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am fairly happy with my understanding of the .NET event model. I think I might be misunderstanding a small nuance of the system.

When I started out putting events into my classes I would use the standard way like so:

public event EventHandler<MyEventArgs> MyEvent;

This meant that anything subscribing to the event would need a method like:

void HandleThatEvent(object sender, MyEventArgs args){...}

Which is nice, but I found that I would rarely care about the sender, so it made a lot of method signatures bloated.

So I switched to declaring my own delegate types

public delegate void MyEventHandler(SomeClass argument);

Which cut down on clutter, but left me with a small problem when it came to writing handlers:

eventImplmentor.MyEvent += HandleThatEvent;
.
.
.
void HandleThatEvent(/*oh, um, what arguments does it take? Intellisense isn't telling me*/)

So I would have to go back to the declaration of the delegate and look and then go back and write them in, or compile it and wait to be told.

So now instead, I'm just using Action, Action<T> or whatever template fits.

public event Action<SomeClass> MyEvent;

So that I can hover over the event and be told what parameters it expects.

My question, after all that: Is there a best practice for declaring events in C#? Should I go back to the EventHandler<T> way, or is Action<T> acceptable?

share|improve this question
add comment

1 Answer 1

For simple, internal event handling, there are those that simply use Action or Action<T>, as you are proposing. I tend to use the standard pattern, including the Sender, even for internal events, because you never know when you might later want to expose a class or event, and I would not want the penalty of having to refactor the event method just to make it public.

I do agree with you that the event handling signature is a bit heavier than it should be for simple scenarios, but it is well designed to handle incremental migration as additional event arguments could become necessary over time. Overall, I would stick with the standard pattern, especially since, as you noted, you only get proper IntelliSense support if you do.

For what it's worth, I put some time into this and came up with a different event handling pattern: Event Signature in .NET — Using a Strong Typed 'Sender'?. The goal here was not to remove the Sender, but to make it generically strong typed as TSender instead of weakly typed as System.Object. It works very well; however, one does lose IntelliSense support when you do this, so there is an unfortunate trade-off.

Overall, I would stick with the standard pattern, but it is interesting to think about potentially better ways to do this.

share|improve this answer
    
Thanks for pointing me to your SO question. It's very interesting. I still don't understand why it's so important that the sender is mandatory. Most of the time I don't care about the sender. Is it just some arbitrary MS rule? –  Matt Ellen Apr 13 '11 at 11:00
    
No, of course you can declare your delegates however you like. It's .NET policy to always include the sender, and it's not entirely a bad idea at that. –  Neil Apr 13 '11 at 11:04
    
@Neil: I understand that it use useful sometimes, but I don't get the policy of always doing it - especially since MS recommend doing events their way. One of the things I really like about events is the ability to decouple classes. If I'm including the object, then it's coupled back up again. If it's just a CLS compliance thing then I can live with that. –  Matt Ellen Apr 13 '11 at 11:46
    
It's coupled back up again only if you use the sender object, otherwise it doesn't matter what gets put as the value of sender since you don't use it. Dependency exists only if you need there to be a dependency. I see where you're coming from, and if object sender disappeared from all code from any server on the planet, I wouldn't stay up nights. –  Neil Apr 13 '11 at 12:19
    
Yes, you can send 'null' as the sender if you really want... But, by including the Sender, the event handler itself could unsubscribe if it wanted to. Overall, though, I would say that knowing the source of the event is usually pretty important. –  Mike Rosenblum Apr 13 '11 at 23:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.