在c#中,如何在将方法附加到事件时传递参数
本文关键字:事件 参数 方法 | 更新日期: 2023-09-27 18:10:44
我试图将参数发送到一个方法,该方法在附加事件侦听器时由事件调用,我可以在一个匿名方法中创建参数,该方法工作良好,但我理想地希望使其更简洁,如下面的例子所示,这是抛出以下编译器错误:
操作符'+='不能应用于'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);
是否有可能像我提议的那样重构代码?
不是那样的。您正在做的是试图将调用 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);
您可以通过不对按值传递的参数使用变量来使它更简洁,像这样:
ConfigFileWritten += (sender, args) => {
SetConfigInterfaceEnabled("IFMDE", true);
};
当编译器看到上述内容时,它不会立即调用SetConfigInterfaceEnabled
。相反,它创建一个可以在运行时调用的对象,这样当您调用它时,就会调用SetConfigInterfaceEnabled
。换句话说,=>
创建了一个委托,允许您延迟对SetConfigInterfaceEnabled
的调用。
但是,当编译器看到
ConfigFileWritten += SetConfigInterfaceEnabled("IFMDE", true);
它将其解释为立即调用SetConfigInterfaceEnabled
的指令,并使用从它返回的委托作为事件处理程序。当然这是不可能的,因为SetConfigInterfaceEnabled
不返回委托。
如果ConfigFileWritten
事件处理程序是您自己的类型,您可以在上升事件时传递参数。从EventArgs
中派生您自己的事件参数类型并传递参数。它可以给你更多的灵活性,你不必在事件处理程序中硬编码参数。