如何检测一个事件处理程序是否为空 [英] How to detect if one eventhandler is null or not

查看:68
本文介绍了如何检测一个事件处理程序是否为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个面板和一个按钮,如下所示:

I create a panel and a button as below :

Panel ThePanel = New Panel();

Button TheButton = New Button();
TheButton.Click += new EventHandler(TheButton_Click);


当我单击按钮时,单击事件将检查ThePanel事件处理程序是否
是否已创建,如果尚未创建,则创建它.代码
我认为在click事件中,应如下所示:


When I click the Button, the click event will check if ThePanel eventhandler
has been created or not, if it has not been created, then create it. The code
in the click event, I suppose, should be as follow :

void TheButton_Click(object sender, EventArgs e)
{
    // (10 != 9) means (if ThePanel.LocationChanged is not created)
    if (10 != 9)
        ThePanel.LocationChanged += new EventHandler(ThePanel_LocationChanged);
}


并且,在完成特定代码后,在ThePanel_LocationChanged事件中,它将删除其LocationChanged事件,如下所示:


And, in ThePanel_LocationChanged event, after having done the specific code, it will remove its LocationChanged event as follow :

void ThePanel_LocationChanged(object sender, EventArgs e)
{
    // do some specific code
    // ......
    
    ThePanel.LocationChanged -= new EventHandler(ThePanel_LocationChanged);

}


我的问题是:

在TheButton.Click事件中,如何检测ThePanel.LocationChanged事件是否已创建? (即(10!= 9)应该用正确的行替换)


My question is :

In TheButton.Click event, how can I detect if ThePanel.LocationChanged event is created or not ? (ie the (10 != 9) should be replaced with correct lines)

推荐答案

事件处理程序不能为null,因为事件处理程序是一个片段代码,方法,匿名与否. 事件句柄的实例只能是 null.

当您使用C#在类中实现事件时,这很容易做到,并且您始终需要执行以下检查:
Event handler can not be null or not, because event handler is a piece of code, a method, anonymous or not. Only the instance of event handle can be null or not.

When you implement an event in your class in C#, it is easy to do and you always need to do this check:
public class MyEvenArguments : System.EventArgs { /*...*/ }

class MyEventTest {
    internal event EventHandler<myevenarguments< MyActionPerforming;
    internal event EventHandler<myevenarguments> MyActionPerformed;
    void MyAction() {
        if (MyActionPerforming != null)
            MyActionPerforming(this, new MyEvenArguments( /*...*/ ));
        //action
        if (MyActionPerformed != null)
            MyActionPerformed(this, new MyEvenArguments( /*...*/ ));
    } //MyAction
} //MyEventTest



但是,在此类之外,即使在派生类中,这种检查也是不可能的:



However, outside of this class this check of impossible, even in the derived class:

class MyEventTestDerived : MyEventTest {
    void Test() {
        if (this.MyActionPerformed != 0) //will not compile!
            System.Console.WriteLine("set up");
    }
}



而已. 在声明事件的类之外无法检查事件实例是否为null.
与委托实例相比,这是事件实例的主要限制之一.事件被设计为使用有限且安全的使用模式.

在任何情况下,检查事件实例是否有用 null 是有用的.类触发事件的用户从不触发该事件.他们可以将事件处理程序添加到事件实例,但是不能检查事件处理程序是否完成.这是面向事件的体系结构的重要概念.触发事件的类的用户无法触发事件,他们直接或间接调用某种方法来触发事件,并且在发生事件时被称为事件处理程序的回调.如果调用了事件处理程序,则意味着事件实例不在null中,如果不是,则不需要-我们永远不需要知道.如果您尝试基于此知识创建某种算法,那么您正在尝试滥用该技术.您应该感谢面向事件的技术,以防止您遭受滥用.

如果您向我解释代码的最终目标,那么我将能够向您解释如何达到目标而又没有您想要的效果.

我要添加其他内容.响应UI事件添加和删除事件处理程序的整个想法是不良设计的标志.在良好的设计中,您永远不要删除事件处理程序并在运行时的开始就设置所有事件处理程序.例如,表单设计器设置了所有从表单构造函数简单调用的方法InitializeComponent.我从不使用Designer来设置事件(并建议每个人都避免这样做,并在自己的代码中设置事件),但是我还从Form构造函数中调用设置事件的代码,或者在如果不是Forms UI,则为运行时的开始.

当您需要禁用事件处理程序调用的效果时,只需要一个布尔标志即可跳过调用.如果触发了事件,则处理程序的第一个动作是测试该标志并立即退出.使用事件,此标志可以是您班上的一个字段;并且您可以对其进行愚蠢的控制.这样,您无需多次添加事件处理程序,也无需删除它.这是一门简单而可靠的学科.

-SA



That''s it. Checking up if the event instance is null is impossible outside the class declaring the event.
This is one of the main limitations of the event instances compared to delegate instances. Events are designed to use limited and safe usage patterns.

There are no situations where checking up of the event instance for null could be useful. The users of the class firing event never fire the event. They can add an event handler to the event instance but cannot check up if it was done or not. This is the important conception of the event-oriented architecture. The user of the class firing the event cannot fire event, they call some method firing the event directly or indirectly and get called a callback called event handler if it happens. If an event handler is called, it means the event instance in not null, if not — we never need to know. If you''re trying to create some algorithm based on this knowledge, you''re trying to abuse the technology. You should be thankful to the event-oriented techniques for keeping you out of the abuse.

If you explain to me the ultimate goal of your code, I will be able to explain you how the goal should be reached without the effect you need.

I want to add something else. The whole idea of adding and removing an event handler in response to UI event is a sign of bad design. In good design you never remove event handler and set all your event handlers in the very beginning of the run time. For example, Form Designer puts sets up all the method InitializeComponent simply called from the form constructor. I never use Designer for setting up events (and recommend everyone to avoid this by all means and set events in your own code), but I also call the code setting my events from the Form constructor or in some other single call which happens in the beginning of run-time if this is not a Forms UI.

When you need to disable effect of the event handler call, you simply need a Boolean flag skipping a call. When event if fired, first action of the handler is to test this flag and exit immediately. This flag(s) can be a field of your class using the events; and you have fool control over it. In this way, you never need to add an event handler more than once and never need to remove it. This is a simple and reliable discipline.

—SA



here
is your solution i think


这篇关于如何检测一个事件处理程序是否为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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