指向带参数的函数的事件

时间:2014-03-25 20:28:39

标签: c# function events delegates arguments

C#中可用于事件的每个函数都只有object sender和eventargs e作为参数。我的问题是,是否有办法通过这个限制?谢谢。

4 个答案:

答案 0 :(得分:0)

  

C#中可用于事件的每个函数都只有object sender和eventargs e作为参数。我的问题是,是否有办法通过这个限制?谢谢。

处理此问题的最常用方法是使用带lambda的闭包:

// Suppose you want to have access to these variables
int data = 42; 
double arg = 5948.2903;

foo.SomeEvent += (s,e) =>
{
     Console.WriteLine("data == {0}, arg == {1}", data, arg); // You can use those here
};

话虽这么说,如果您创建事件并订阅它,您可以使用自定义EventArgs类型(甚至中断约定并使事件成为任何委托你选择的类型)。您还可以创建一个自定义类来处理事件,并将数据传递给它(这实际上是上面的闭包/ lambda方法)。

答案 1 :(得分:0)

事件 您可以使用所需的任何签名轻松创建自己的事件。以下是如何声明不提供参数的事件:

public event Action SomeEvent;

这仅仅是事件在发件人和EventArgs对象中传递的惯例。它绝不是语言的要求。

但是,您只能更改自己类型的事件签名,您无法在您无法控制的课程中更改事件的签名。这里没有选择;处理程序必须匹配事件的签名才能使其附加。如果要使用其他签名调用方法,则唯一的选择是创建具有正确签名的处理程序,该签名调用具有其他签名的方法。你可以简化执行此操作所需的代码量,正如Reed在他的回答中提到的那样,使用lambda:

SomeOtherEvent += (sender, args) => SomeMethod(localVariableToCloseOver);

答案 2 :(得分:0)

您可以创建自己的eventargs类,该类继承eventargs并提供您需要的任何数据。

答案 3 :(得分:0)

  

C#中可用于事件的每个函数只有object sendereventargs e作为参数

事实并非如此 - 每个需要EventHandler delagate 的事件都有这些参数。不同事件有不同的事件处理程序类型

Control.Click,例如只需要一个EventHandler,因为通用点击事件所需的唯一相关信息是点击了什么sender)。

另一方面,

MouseClick传递MoiuseEventArgs,其中包含特定于该事件的其他信息,例如点击的按钮,坐标,点击的类型(单击或双击)等等。)

因此,如果您在活动中需要更多信息,最简单的方法是继承EventArgs并将该类型用作EventHandler<T>的通用参数:

public class MyEventArgs : EventArgs
{
   public string MyEventData {get; set;}
}

public event EventHandler<MyEventArgs> MyEvent;

然后,您可以提供委托或lambda来处理事件。

MyEvent += (s, me) => me.MyEventData = "foo";