如何分离动态制作的处理程序 [英] How to detach a dynamically made handler

查看:95
本文介绍了如何分离动态制作的处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我在网上看过以下代码示例:



Hi,

I have seen the following code example online:

framesReplay.FrameReady += frame => synchronizationContext.Send(state => AllFramesReady.Raise(new ReplayAllFramesReadyEventArgs { AllFrames = frame }), null);





这是在同一方法中附加代码的事件,而不是专门用于处理事件的另一种方法,例如:





This is attaching an event in code within the same method rather than having another method dedicated for handling the event such as:

        framesReplay.FrameReady += eventHandlerMethod;

private void eventHandlerMethod(EvantArgs args)
{

            synchronizationContext.Send(state => AllFramesReady.Raise(new ReplayAllFramesReadyEventArgs { AllFrames = frame }), null);
}





我如何分离处理程序?正常方式:





How do I therefore detach the handler? Normal way of:

framesReplay.FrameReady -= eventHandlerMethod;





谢谢!



Thanks!

推荐答案

当您使用Lambda表示法定义事件处理程序时,生成的方法是匿名的,因为它不可用一旦创建,由程序员操纵,除非你保留对它的引用。这实际上是相同的可见性逻辑,适用于您在某个方法,类等的范围中创建的任何内容。



和当然,您可以维护对内联创建的事件处理程序的引用;您可以随时以标准方式删除从多播代理中删除事件处理程序的引用。



假设您在WinForm上有两个Button控件, button1,button2:考虑以下代码:
When you define an Event Handler using Lambda notation, the resulting method is "anonymous" in the sense it's not available to be manipulated by the programmer once it has been created unless you keep a reference to it. That's really the same "visibility" logic that applies to anything you create within the scope of a some method, class, etc.

And, of course, you can maintain a reference to an Event Handler created "inline;" a reference you can, at any time, remove in the standard way you remove an Event Handler from a Multicast Delegate.

Assume you have two Button Controls on a WinForm, button1, button2: consider the following code:
// EventHandler variable definitions
EventHandler Button1Click;
MouseEventHandler Button2MouseDown;

// boolean used to toggle connected/removed state of EventHandlers 
private bool AreEventsWired = false;

private void button1_Click(object sender, EventArgs e)
{
    AreEventsWired = ! AreEventsWired ;

    if (AreEventsWired )
    {
        // use Lambda notation to create a Click EventHandler [1]
        Button1Click = (object obj, ea) => { MessageBox.Show("Button1 Click"); };
        // wire-up the EventHandler to the Click Event Delegate of the Button
        button1.Click += Button1Click;

        // note for MouseDown we need a MouseEventArgs argument [2]
        Button2MouseDown = (object obj, MouseEventArgs ea) => { MessageBox.Show("Button2 MouseDown"); };
        button2.MouseDown += Button2MouseDown;
    }
    else
    {
        // remove the EventHandlers
        button1.Click -= Button1Click;
        button2.MouseDown -= Button2MouseDown;
    }
}

你能预测第一次和第二次会发生什么或不会发生,你在运行时点击button1吗?



[1]请注意,这里我们没有在Lambda表单EventHandler声明中指定参数类型:编译器假定我们使用默认的Types,Object和EventArgs。



[2]请注意,这里编译器需要我们指定两个 Types,Object和MouseEventArgs,因为MouseEventArgs不是 default EventHandler event-argument Type。



讨论:如果你真的想到它,你会看到我们在上面的例子中所做的一切只是使用一种奇特的方式来创建一个定义的EventHandler。它的用法与在单独的方法中创建命名的EventHandler完全相同。



因此,当您的代码确实要求您保留对EventHandler的引用时,除非你对编写Lambda表示法的行为感到非常激动:你可能会问自己,编写代码是否有任何优势。



进一步说明:如果是C#让我们以编程方式直接访问MultiCast Delegates的胆量,这样我们就可以动态地检查哪些EventHandler被连线,并乱用它们:那么,那将是另一种语言?

Can you predict what will happen, or not happen, the first and second time, you click on button1 at run-time ?

[1] note that here we do not specify the parameter Types in our Lambda form EventHandler declaration: the compiler assumes that we are using the default Types, Object, and EventArgs.

[2] note that here the compiler requires we specify both Types, Object, and MouseEventArgs because MouseEventArgs is not the default EventHandler event-argument Type.

Discussion: if you really think about it you'll see that all we have really done in the above example is just use a fancy way to create a defined EventHandler. Its usage will be exactly the same as if you had created a named EventHandler in a separate method.

So, when your code does require you keep a reference to an EventHandler, unless you are really thrilled by the act of writing Lambda notation: you might well ask yourself if there's any advantage to writing code this way.

Further Out: if C# gave us direct access programmatically to the "guts" of MultiCast Delegates, so we could dynamically inspect which EventHandlers were wired-up, and mess around with them: well, that would be another language ?


这是不可能的。不是你描述它的方式。在您的代码中,您声明了一个匿名委托 - 它没有名称,因此您无法将其删除...



首先考虑SA的评论 - 您可以删除需要通过良好的代码设计进行分离。



其次,您对匿名委托没有任何好处,因为编译器会将其作为您以前使用的方法包装起来宣布。所以,如果它是为了更好的代码,但你也必须做分离的事情,你必须放弃......
It's not possible. Not in the way you describe it. In your code you declared an anonymous delegate - it has no name, so you can't remove it...

First of all consider SA's comment - you can remove the need for detach by good code design.

Second, you do not gain nothing with the anonymous delegate, because the compiler will wrap it up as a method you used to declare. So if it's for nicer code, but you also must do the detach thing, you must give in...


这篇关于如何分离动态制作的处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆