【问题标题】:Check if event has any listeners?检查事件是否有监听器?
【发布时间】:2011-06-09 10:39:19
【问题描述】:

是否可以检测事件是否有任何监听器? (如果没有人需要,我需要处理我的事件提供程序对象)

【问题讨论】:

    标签: c# .net clr


    【解决方案1】:

    假设该类位于第 3 方库中且无法修改:

        public class Data
        {
           public event EventHandler OnSave;
           //other members
        }
    

    在你的程序中:

        Data d = new Data();
        d.OnSave += delegate { Console.WriteLine("event"); };
        var handler = typeof(Data).GetField("OnSave", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(d) as Delegate;
    
        if (handler == null)
        {
            //no subscribers
        }
        else
        {
            var subscribers = handler.GetInvocationList();
            //now you have the subscribers
        }
    

    【讨论】:

    • 看来调用 GetInvocationList 并不是必须的,检查处理程序是否为 null 就足够了。我说的对吗?
    • @user626528:是的,你是对的。在这个例子中,我展示了一些在某些情况下可能有用的东西。
    • 如果在没有添加 OnSave 事件时 handler 为 null,那么上面的代码应该有一个 null 检查,否则会出错。
    • 如果您确实可以访问库源,这将非常方便,但是您的代码在不同程序集中的解决方案中是分开的。无论如何,有另一个很好的答案徽章。
    【解决方案2】:

    您可以检查事件是否为 != null。

    顺便说一句,在 C# 中,每次引发事件时都需要进行此检查:

    if (TheEvent != null) {
        TheEvent(this, e);
    }
    

    原因正是为了检查事件是否有任何监听器。

    编辑
    由于您无法从类外部访问 TheEvent,因此您可以实现一个进行检查的方法:

    public class TheClass {
        public bool HasEventListeners() {
            return TheEvent != null;
        }
    }
    

    【讨论】:

    • 我需要在对象之外检查它,因为它是由第 3 方制作的。我需要检查是否有人订阅了对象的事件,如果没有订阅则处理它。
    • 我不认为你可以,你需要一个方法包装器
    • 你是说最后一句中的“Since you can't access...”吗?
    【解决方案3】:
    void Main()
    {
        Console.WriteLine(ContainsOnSomethingEvent()); // false
        OnSomething += (o,e) => {};
        Console.WriteLine(ContainsOnSomethingEvent()); // true
    }
    EventHandler mOnSomething;
    
    event EventHandler OnSomething {
        add { mOnSomething = (EventHandler)EventHandler.Combine(mOnSomething, value);   }
        remove { mOnSomething = (EventHandler)EventHandler.Remove(mOnSomething, value); }
    }
    
    public bool ContainsOnSomethingEvent() {
        return mOnSomething != null && mOnSomething.GetInvocationList().Length > 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-16
      • 2022-01-13
      • 1970-01-01
      • 2012-07-12
      • 1970-01-01
      • 2015-01-15
      相关资源
      最近更新 更多