为什么事件处理程序在Visual Studio中自动创建时使用Object Sender

时间:2015-02-27 10:02:24

标签: c# events visual-studio-2013 eventhandler

例如,如果我有:

初始化控制

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

事件处理程序

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

    //Do some stuff to MyControl
}

sender始终是MyControl对象并不是隐含的吗?

但是事件处理程序

void mc_MouseUp(MyObject sender, MouseButtonEventArgs e)
{
}

给出错误:

  

mc_MouseDown没有重载匹配委托   System.Windows.Input.MouseButtonEventHandler

为什么会这样?

3 个答案:

答案 0 :(得分:2)

它可以决定其事件的签名(它想要使用的代理),大多数事件签名总是使用类型为sender的第一个参数{ {1}}。这是在guidelines

之后
  
      
  • 返回类型为Void

  •   
  • 第一个参数名为 sender ,类型为Object。这是引发事件的对象。

  •   
  • 第二个参数名为 e ,类型为EventArgs或派生类EventArgs。这是特定于事件的数据。

  •   

您可以使用相同的处理程序代码来侦听来自不同类型的多个控件的多个事件,因此限制发件人类型不一定是好的。

在.NET 3.5中引入delegate variance之前,这些指南更有意义。

答案 1 :(得分:1)

  

是不是隐含发送者永远是MyControl对象?

没有。 mc_MouseUp只是一个与MouseUp的委托签名匹配的方法。它可以在任何调用者的内部调用(如果声明为 private ),它可以传递任意object。如果Control中的派生类型决定将FooBar作为对象发件人发送,则可以这样做。

  

mc_MouseDown没有重载匹配委托   System.Windows.Input.MouseButtonEventHandler

     

为什么会这样?

规范声明:

  

•对于每个值参数(没有ref或out修饰符的参数),   标识转换(第6.1.1节)隐式引用转换   (§6.1.6)存在从D中的参数类型到相应的   M。

中的参数类型

由于没有从objectMyObject的身份或隐式引用转换,因此无法编译。

答案 2 :(得分:0)

  
    

mc_MouseDown没有重载匹配委托System.Windows.Input.MouseButtonEventHandler

  

因为MouseEventHandler事件处理程序声明为

public delegate void MouseEventHandler(
    Object sender,
    MouseEventArgs e
)

您需要提交相同的签名。

注意

如果是这样的话

public delegate void MouseEventHandler(
    MyObject sender,
    MouseEventArgs e
)

然后签名都有效。

  

我的观点是,通过将MyObject指定为第一个参数而不是object,可以使范围变大。