如何查找事件是否已连接

如何查找事件是否已连接

本文介绍了C#如何查找事件是否已连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够查明某个事件是否已连接.我环顾四周,但只找到了涉及修改包含事件的对象内部的解决方案.我不想这样做.

I want to be able to find out if an event is hooked up or not. I've looked around, but I've only found solutions that involved modifying the internals of the object that contains the event. I don't want to do this.

这是一些我认为可行的测试代码:

Here is some test code that I thought would work:

// Create a new event handler that takes in the function I want to execute when the event fires
EventHandler myEventHandler = new EventHandler(myObject_SomeEvent);
// Get "p1" number events that got hooked up to myEventHandler
int p1 = myEventHandler.GetInvocationList().Length;
// Now actually hook an event up
myObject.SomeEvent += m_myEventHandler;
// Re check "p2" number of events hooked up to myEventHandler
int p2 = myEventHandler.GetInvocationList().Length;

请注意以上内容是完全错误的.我认为当我将事件挂接到它时,myEventHandler 中的invocationList"会以某种方式自动更新.但不,事实并非如此.this 的长度总是返回为一.

Unfort the above is dead wrong. I thought that somehow the "invocationList" in myEventHandler would automatically get updated when I hooked an event to it. But no, this is not the case. The length of this always comes back as one.

是否可以从包含事件的对象外部确定这一点?

Is there anyway to determine this from outside the object that contains the event?

推荐答案

C# event 关键字呈现出一种微妙的错觉,那就是事件有一个调用列表.

There is a subtle illusion presented by the C# event keyword and that is that an event has an invocation list.

如果您使用 C# event 关键字声明事件,编译器将在您的类中生成一个私有委托,并为您管理它.每当您订阅事件时,都会调用编译器生成的 add 方法,该方法将事件处理程序附加到委托的调用列表中.该事件没有明确的调用列表.

If you declare the event using the C# event keyword, the compiler will generate a private delegate in your class, and manage it for you. Whenever you subscribe to the event, the compiler-generated add method is invoked, which appends the event handler to the delegate's invocation list. There is no explicit invocation list for the event.

因此,获得委托的调用列表的唯一方法是最好:

Thus, the only way to get at the delegate's invocation list is to preferably:

  • 使用反射访问编译器生成的委托或
  • 创建一个非私有委托(可能是内部委托)并手动实现事件的添加/删除方法(这样可以防止编译器生成事件的默认实现)

这是一个演示后一种技术的示例.

Here is an example demonstrating the latter technique.

class MyType
{
    internal EventHandler<int> _delegate;
    public event EventHandler<int> MyEvent;
    {
        add { _delegate += value; }
        remove { _delegate -= value; }
    }
}

这篇关于C#如何查找事件是否已连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 22:46