且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何检测一个事件处理程序是否为空

更新时间:2023-11-25 19:11:52

事件处理程序不能为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