将自己的参数发送给事件处理程序?

时间:2011-03-11 21:27:29

标签: c# event-handling

我正在使用AssemblyResolve。这是我的代码,然后我的问题如下:

var a = AppDomain.CurrentDomain;
a.AssemblyResolve += new ResolveEventHandler(HandleIt);

Private Assembly HandleIt(object sender, ResolveEventArgs args){
    //Does stuff, returns an assembly
}

所以我将HandleIt添加到我的AssemblyResolve事件中。我如何将它添加到该事件并传递一个参数,如:

a.AssemblyResolve += new ResolveEventHandler(HandleIt(AnArgument));

自从HandleIt接受参数后,这就让我失望了,但是当它被添加到AssemblyResolve事件时,没有一个被明确地传递掉。我希望有类似的东西:

a.AssemblyResolve += new ResolveEventHandler(HandleIt(aSender,someArgs));

所以是的,我只想在将其添加到我的AssemblyResolve事件时能够向HandleIt函数发送另一个参数。

希望这是有道理的,谢谢。

附录:

if(aBool){
    a.AssemblyResolve += new ResolveEventHandler(HandleA);
}
else{
    a.AssemblyResolve += new ResolveEventHandler(HandleB);
}

HandleA(object sender, ResolveEventArgs args){
    Handle(true);
}
HandleB(object sender, ResolveEventArgs args){
    Handle(false);
}
Handle(bool isA){

}

-vs -

if(aBool){
    a.AssemblyResolve += (object s, ResolveEventArgs a) => Handle(s,a,true);
}
else{
    a.AssemblyResolve += (object s, ResolveEventArgs a) => Handle(s,a,false);
}

Handle(object sender, ResolveEventArgs args, bool isA){

}

4 个答案:

答案 0 :(得分:7)

当事件被触发时,如果你想绑定其他参数,你可以将参数传递给方法,你可以用lambdaexpression

var a = AppDomain.CurrentDomain;
a.AssemblyResolve += (object s,ResolveEventArgs a) => HandleIt(s,a,someArgument);

Private Assembly HandleIt(object sender, ResolveEventArgs args, SomeType arg){
    //Does stuff, returns an assembly
}

其中someArgument是您要绑定的值。

这主要是使用lambdas来部分应用函数。 C#不直接支持的东西,但在其他语言中很常见。部分应用与当然存在于F#和Haskell等语言中的Currying密切相关(因为该概念的名称来自Haskell Curry)和各种其他功能语言。它们的结果类型不同。

它们都与闭包相关(如上面代码中的概念所示),并且在不支持部分应用或currying的语言中,您可以使用闭包来完成类似的操作。但请注意,闭包与部分应用的区别在于可能会产生一些令人惊讶的错误。例如。

int i = 1;
Func<int> f = () => i;
i = 2;

System.Console.WriteLine(f());

2打印到控制台。因为闭包会将引用捕获到变量而不是所述变量的值。当关闭for循环的循环变量时,这是for循环中的常见错误。

答案 1 :(得分:2)

AppDomain.CurrentDomain将引发事件并传递参数,+ =行只是在事件中注册一个处理程序,参数就没有任何意义。

打个比方:

您向邮递员注册了您的地址,之后他将邮件发送到该地址。当您在邮局注册时,您不会将您想要的邮件交给他们!

答案 2 :(得分:1)

这是不可能的。 HandleIt在这种情况下是一个委托,并且必须匹配ResolveEventHandler的签名

a.AssemblyResolve += new ResolveEventHandler(HandleIt);

在这一行中设置它只是告诉代码在引发AssemblyResolve时要执行什么,引发AssemblyResolved事件的东西将传递它的参数。您可以使用自己的参数重新引发另一个事件,并将其挂钩到另一个处理程序(或者只是调用方法)。

编辑:或许你可以和Lamda一起:o

答案 3 :(得分:0)

更具技术性:您正在使用该事件向您的方法注册委托。这不是对方法的调用。 它有点类似于:

Action<object, ResolveEventArgs> handleItDelegate = HandleIt;

触发事件时,将调用委托。我的样本的类比是:

handleItDelegate(sender, eventArgs);

更新:
在评论中,您澄清了您想要实现的目标:您想要触发事件,因此您的程序集已加载。你不能这样做,你认为它的工作方式。要手动加载程序集,只需这样做,不需要事件。当运行时尝试解析引用的程序集但无法找到它时,将调用该事件。