c# - 如何在运行时检索事件的订阅者列表?

标签 c# winforms events

使用委托(delegate)时,我可以使用 Delegate.GetInvocationList()在运行时检索委托(delegate)的调用列表的方法。

有没有办法访问与事件关联的订阅者列表?我从这个 example (SO#1237001) 运行了代码即时窗口允许我将 SecondChange 事件转换为 System.MultiCastDelegate,然后调用 GetInvocationList 方法。

但是,在我的场景中,我正在使用 System.Windows.Forms.DataGridView,我想在运行时检查 CellClick 事件的调用列表。但是,当我尝试对 CellClick 进行任何类型的转换时,我收到以下错误:

The event 'System.Windows.Forms.DataGridView.CellClick' can only appear on the left hand side of += or -=

我可以看到这些事件的声明有明显的差异。在时钟示例中,事件声明如下:

public event Func<DateTime, bool> SecondChange;

在 DataGridView 中,事件声明如下:

[SRDescription("DataGridView_CellClickDescr"), SRCategory("CatMouse")]
public event DataGridViewCellEventHandler CellClick
{
    add
    {
        base.Events.AddHandler(EVENT_DATAGRIDVIEWCELLCLICK, value);
    }
    remove
    {
        base.Events.RemoveHandler(EVENT_DATAGRIDVIEWCELLCLICK, value);
    }
}

为什么可以在 Clock 示例上调用 GetInvocationList,而不能在 DataGridView 事件上调用?我有什么方法可以从 GetInvocationList 返回的 DataGridView 事件中获取相同类型的信息?

最佳答案

event 的全部意义在于它定义了(仅)add/remove API(就像属性如何定义 get /设置).

事件的重点是在外部您不能这样做(访问订阅者)。我猜想在“时钟”示例中,访问列表的代码声明事件的类型中;这很好:在类型内部,您可以完全访问支持实现(通常是委托(delegate)字段)。

在外部,您应该只关心您自己的处理程序,您已经知道这些处理程序,因为您订阅了它们。存在获取支持者的尝试,但它很脆弱,不推荐使用。例如,在这种情况下,它使用 EventHandlerList

为什么需要这个?这通常意味着您做错了什么(抱歉,但确实如此)。

关于c# - 如何在运行时检索事件的订阅者列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1930374/

相关文章:

c# - 如何创建一个 web Api 具有 http post 功能,它可以从正文中获取任何动态 json 内容并能够将其解析为字符串

c# - InsertCommand.Parameters.为日期时间添加大小参数

c# - 动态编译以提高性能

c# - 未调用 .NET Core ApiController 方法

c# - Windows窗体中的Panel和ScrollBar

java - 为什么我没有通过 Com4J 接收 COM 事件?

c# - 如何循环遍历所有目录中的所有文件并仅获取文件的类型?

c# - Form.Parent 和 StartPosition.CenterParent

javascript - 如何在 .on 方法中给出多个事件和处理程序?

Javascript 事件自定义属性消失