如何在c#中将方法附加到事件时传递参数

时间:2013-04-24 10:05:28

标签: c# events delegates

我正在尝试将参数发送到附加事件侦听器时由事件调用的方法,我可以在匿名方法中创建参数,但是我会理想地希望使其更简洁,如示例中所示下面,这是抛出以下编译器错误:

  

运算符'+ ='不能应用于'System.EventHandler'和'void'类型的操作数

ConfigFileWritten += (sender, args) =>
{
    string prefix = "IFMDE";
    bool enabled = true;

    SetConfigInterfaceEnabled(prefix, enabled);
};

//this line is throwing a compiler error 
ConfigFileWritten += SetConfigInterfaceEnabled("",true);

是否有可能像我提议的那样重新编码代码?

3 个答案:

答案 0 :(得分:4)

不是那样的。你在做什么试图将调用 SetConfigInterfaceEnabled的结果作为事件处理程序附加,这当然是不可能的(结果必须是EventHandler委托,但它只是void)。

你能做的是

ConfigFileWritten += (s, e) => SetConfigInterfaceEnabled("",true);

这里的事件处理程序是一个lambda函数,它具有相应的签名(带有两个隐式类型的参数),然后调用SetConfigInterfaceEnabled。其唯一目的是使SetConfigInterfaceEnabled的签名适应预期的EventHandler

为了完整起见,我应该提一下,尽管需要这样做是非常不寻常的,但是如果SetConfigInterfaceEnabled是一个创建委托的工厂方法,那么你可以使用像你提出的语法:

EventHandler SetConfigInterfaceEnabledDelegate(string s, bool b)
{
    return (o, e) => SetConfigInterfaceEnabled(s, b);
}

ConfigFileWritten += SetConfigInterfaceEnabledDelegate("", true);

答案 1 :(得分:1)

您可以通过不为值传递的参数使用变量来使其更简洁,如下所示:

ConfigFileWritten += (sender, args) => {
    SetConfigInterfaceEnabled("IFMDE", true);
};

当编译器看到上述内容时,它不会立即调用SetConfigInterfaceEnabled。相反,它创建了一个可以在运行时调用的对象,这样当你调用它时,SetConfigInterfaceEnabled就会被调用。换句话说,=>会创建一个委托,允许您将呼叫推迟到SetConfigInterfaceEnabled

然而,当编译器看到这个

ConfigFileWritten += SetConfigInterfaceEnabled("IFMDE", true);

它将其解释为立即调用SetConfigInterfaceEnabled 的指令,并使用从其返回的委托作为事件处理程序。当然这是不可能的,因为SetConfigInterfaceEnabled没有返回委托。

答案 2 :(得分:0)

如果ConfigFileWritten事件处理程序属于您自己的类型,您可以在上升事件时传递argumemns。从EventArgs派生您自己的事件参数类型并传递参数。它可以为您提供更大的灵活性,而且您不必在事件处理程序中对参数进行硬编码。