✅ Design of events
Hi!
I have a question about utilization of events. Don't know many real life production examples by myself, but counting on your experience 😉
I've noticed that EventHandler delegate takes two parameters: object sender and EventArgs or other defined type. That means that in subscribers we can't be sure what is the sender and what are its properties/methods. So what's the main purpose (by design) of this "sender" parameter, shall it be used to check what type it is and take actions based on that? I am aware that I can create my own type of event instead of using EventHandler, but anyway I'm curious about the real life usage of the sender object.
17 Replies
That's specifically about WPF events?
If so, then the sender is a reference to the control that called the event
Like, a click event of a button will have a reference to that button as the sender
Other than that, the sender is generally a reference to the calling class
Thanks, I didn't mean WPF specific but is it a general rule that subscribers should be prepared that event can be raised by different type of classes? Otherwise, I think we could use other handler like:
public delegate void CustomHandler<SenderType, EventArgsType>(SenderType sender, EventArgsType e)
.
So the main reason of my question is that I want to understand why authors utilize this ambigous "object" as a sender. Probably there is some logic behind that but I know too litle real life examples to deduct that.There's a
EventHandler<T>
override that takes the type of the events object
As to why...?
Old code would be my best bet
Someone did it this way some days, nobody bothered to update it because it would be a breaking change or whatever, and that's where we're at
For custom code, I would probably just not use EventHandlers
but rather Func
s and Action
s, or a named delegate insteadAngius
REPL Result: Failure
Console Output
Exception: ExitException
Compile: 705.722ms | Execution: 68.717ms | React with ❌ to remove this embed.
Something like this, without using
EventHandler
thx for your input and the example 😉 Probably I will have to find my way of dealing with that, but that comes with time
good to know many ways to solve things
It's
object
because that's the common abstraction and simplest to code against for the purpose of the parameter, which you have summarized perfectly.
I agree with @ZZZZZZZZZZZZZZZZZZZZZZZZZ , you'd want an event handler delegate that matches the specific usecase. Sometimes that includes checking the sender due to subscriptions to several publishers of the same event.Also, that pattern comes from C# 1, before we had generics
But, generics will only take you so far. Sure you could do:
But what if A was subclassed?
Then you could do:
And that
sender
parameter would be typed as an instance of A
, even though it was an instance of B
which raised it.
That happens loads in UI frameworks, where events are defined by classes near the base of the object hierarchy, but you often interact with classes much further down
Obviously if you subscribe to TextBox.TextChanged
you expect the sender
parameter to be an instance of TextChanged
. You're not going to get some other control raising that event and inserting itself as the sender
parameter.
But sometimes you have a list of 20 textboxes, and you want to do something when the text changes in any of them, and you don't want to define 20 handlers. So you define a single handler, and you use that sender
parameter to interact with the specific textbox which raised the event
Do bear in mind the reason that the EventHandler
pattern exists, which is forwards compatibility. You can't add extra parameters to an Action
without it being a breaking change, but you can add additional properties to an EventArgs
subclass
That's why ☝️Thanks for your insight @canton7.
then won't having specific TextBox as a sender class be good enough? However I may imagine that there are kinds of text boxes which you deal with differently...
Isn't that is what happens though?
@canton7 Not sure I understood you, as I mean typing instead of
object sender
, TextBox sender
(or smth like that).
But anyway, I'm now playing around a bit with Avalonia UI and its events, which may give me more insight, then I may "feel" more what you have writtten.
Thank you both @ZZZZZZZZZZZZZZZZZZZZZZZZZ and @canton7
Btw. It's my first post in this channel, should I mark it as "answered" or smth like that?$close
If you have no further questions, please use /close to mark the forum thread as answered
Not sure I understood you, as I mean typing instead of object sender, TextBox sender (or smth like that).Happy to clarify, but I'm afraid I'm not sure what your confusion is
@canton7 You've written:
Obviously if you subscribe to TextBox.TextChanged you expect the sender parameter to be an instance of TextChanged. You're not going to get some other control raising that event and inserting itself as the sender parameter. But sometimes you have a list of 20 textboxes, and you want to do something when the text changes in any of them, and you don't want to define 20 handlers. So you define a single handler, and you use that sender parameter to interact with the specific textbox which raised the eventI've assumed that you meant using
object sender
instead of e.g. TextBox.TextChanged sender
make that (interaction without having 20 handlers) possible. I thought the latter makes it possible too (and the type in handler parameter precise kind of sender you are dealing with).Oops, * Obviously if you subscribe to TextBox.TextChanged you expect the sender parameter to be an instance of TextBox.
My point was that there's no harm casting the
object sender
to TextBox
, since you know that it will always be an instance of TextBox
Hmm, no, I can't spot itThanks, now I get your point. I think I'll try to use strongly typed param in handler definition, unless some framework force me to use
object
. But I may of course change my opinion after having some more practice 😉 Good talk, thank you, I'm closing the topic now. See you! 🙂