繁体   English   中英

是否有必要在删除代理链之前检查处理程序是否存在?

[英]Is it necessary to check if a handler exists in a delegate chain before removing it?

我有一个基于委托的消息传递系统的小片段,您可以SubscribeUnsubscribe事件处理程序,并Raise新事件。

在我的Unsubscribe方法中,我检查以确保处理程序首先存在,然后再删除它。

我的问题是:这项检查是否必要? 即我不能这样做:

dic[type] -= handler;

无:

if (handler exists)
    dic[type] -= handler;

如果是这样,为什么? - 我尝试了检查而不是检查,它们都产生了相同的实际结果。 不知道为什么我更愿意使用其中任何一个。

码:

    public abstract class GameEvent { }

    private static class EventManagerInternal<T> where T : GameEvent
    {
        private static Dictionary<Type, Action<T>> dic = new Dictionary<Type, Action<T>>();

        public static void Subscribe(Action<T> handler)
        {
            Type type = typeof(T);
            if (!dic.ContainsKey(type)) {
                dic[type] = handler;
                Console.WriteLine("Registered new type: " + type);
            }
            else {
                // make sure the handler doesn't exist first
                bool hasHandlerSubscribed = dic[type].GetInvocationList().Any(h => h.Equals(handler));
                if (hasHandlerSubscribed) {
                    Console.WriteLine(handler.Method.Name + " has already subbed to an event of type " + type);
                    return;
                }
                dic[type] += handler;
            }
            Console.WriteLine("Method " + handler.Method.Name + " has subbed to receive notifications from " + type);
        }

        public static void Unsubscribe(Action<T> handler)
        {
            Type type = typeof(T);

            // make sure the type exists
            if (!dic.ContainsKey(type)) {
                Console.WriteLine("Type " + type + " hasn't registered at all, it doesn't have any subscribers... at least not in my book...");
                return;
            }

            // get the methods that the delegate points to
            // to see if the handler exists or not
            bool exist = dic[type].GetInvocationList().Any(h => h.Equals(handler));
            if (!exist) {
                Console.WriteLine("Method " + handler.Method.Name + " hasn't registered at all, for notifications from " + type);
                return;
            }

            // remove the handler from the chain
            dic[type] -= handler;
            Console.WriteLine("handler " + handler.Method.Name + " has been removed. it won't take any notifications from " + type);

            // if there's no more subscribers to the "type" entry, remove it
            if (dic[type] == null) {
                dic.Remove(type);
                Console.WriteLine("No more subscribers to " + type);
            }
        }

        public static void Raise(T e)
        {
            Action<T> handler;
            if (dic.TryGetValue(e.GetType(), out handler)) {
                handler.Invoke(e);
            }
        }
    }

示例用法:(通过包装器 - 我只是认为Class.DoSomething<T>Class<T>DoSomething更好 - 有一个很好的理由我为什么不得不去做这个设置:)不是这里的重点...... )

        Player p = new Player();
        EventManager.Subscribe<OnRename>(OnRenameHandler);
        EventManager.Subscribe<OnRename>(AnotherOnRenameHandler);
        EventManager.Raise(new OnRename());
        EventManager.Unsubscribe<OnRename>(OnRenameHandler);
        etc

我的问题是:这项检查是否必要?

不它不是。

为什么?

这很简单,检查由您正在使用的操作员完成。 如果要删除的处理程序不存在,而不是抛出异常,它专门设计为什么都不做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM