简体   繁体   中英

Why do event handlers use Object Sender when being automatically created in Visual Studio

For example if I had:

Initialize Control

MyControl mc = new MyControl();
mc.MouseUp += mc_MouseUp;

Event Handler

void mc_MouseUp(object sender, MouseButtonEventArgs e)
{
    //annoying cast...
    MyControl control = (MyControl)sender;

    //Do some stuff to MyControl
}

is it not implicit that sender will always be a MyControl object?

but yet the event handler

void mc_MouseUp(MyObject sender, MouseButtonEventArgs e)
{
}

Gives an error:

No Overload for mc_MouseDown matches delegate System.Windows.Input.MouseButtonEventHandler

Why is this?

Its the control that gets to decide on the signatures for its events (what delegates it wants to use), and most event signatures always use a first parameter called sender of type object . That follows the guidelines :

  • The return type is Void .

  • The first parameter is named sender and is of type Object . This is the object that raised the event.

  • The second parameter is named e and is of type EventArgs or a derived class of EventArgs .This is the event-specific data.

You can use the same handler code to listen to multiple events from multiple controls, of different types, so it wouldn't be necessarily good to restrict the sender type.

These guidelines made a lot more sense before delegate variance was introduced in .NET 3.5.

is it not implicit that sender will always be a MyControl object?

No. mc_MouseUp is simply a method defined which matches the delegate signature of MouseUp . It can be invoked inside of your class (if declared private ) by any caller, which can pass an arbitrary object . If your derived type from Control decides to send FooBar as the object sender, he can do so.

No Overload for mc_MouseDown matches delegate System.Windows.Input.MouseButtonEventHandler

Why is this?

The specification states:

• For each value parameter (a parameter with no ref or out modifier), an identity conversion (§6.1.1) or implicit reference conversion (§6.1.6) exists from the parameter type in D to the corresponding parameter type in M.

Since there isn't an identity or implicit reference conversion from object to MyObject , this doesn't compile.

No Overload for mc_MouseDown matches delegate System.Windows.Input.MouseButtonEventHandler

Because MouseEventHandler event handler is declared as

public delegate void MouseEventHandler(
    Object sender,
    MouseEventArgs e
)

You are required to refer same signature.

Note

If it was like this

public delegate void MouseEventHandler(
    MyObject sender,
    MouseEventArgs e
)

Then both the signature would have valid.

My point is you can make scope big not small by specifying MyObject as first parameter instead of object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM