Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.NET-从对象中删除所有侦听器事件处理程序_.net_Events_Handlers - Fatal编程技术网

.NET-从对象中删除所有侦听器事件处理程序

.NET-从对象中删除所有侦听器事件处理程序,.net,events,handlers,.net,Events,Handlers,我有一个objectRaiser,它可以发布事件,例如事件“PropertyChanged”。 我还有另一个objectListener,它监听第一个objectRaiser引发的事件 如何从objectRaiser实例中删除objectListener侦听的事件处理程序 我需要重复一些重要的事情:remove的事件处理程序来自objectListener。不适用于我从objectRaiser中删除所有发布。我在另一个问题中看到了这一点,但似乎并不能解决我的问题 问候并感谢您的帮助。来自内部的o

我有一个objectRaiser,它可以发布事件,例如事件“PropertyChanged”。 我还有另一个objectListener,它监听第一个objectRaiser引发的事件

如何从objectRaiser实例中删除objectListener侦听的事件处理程序

我需要重复一些重要的事情:remove的事件处理程序来自objectListener。不适用于我从objectRaiser中删除所有发布。我在另一个问题中看到了这一点,但似乎并不能解决我的问题


问候并感谢您的帮助。

来自内部的
objectRaiser

MyEvent = null;
namespace ObjectEvents
{
    class Program
    {
        private class ObjectRaiser
        {
            public event EventHandler PropertyChange;

            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                    PropertyChange(this, new EventArgs());
                }
            }
        }

        private class ObjectListener
        {
            private ObjectRaiser or;

            public ObjectListener(ObjectRaiser or)
            {
                this.or = or;
                or.PropertyChange += new EventHandler(PropertyChange);
            }

            public void PropertyChange(object sender, EventArgs e)
            {
                Console.WriteLine("I'm listening!");
            }

            public void RemoveHandlers()
            {
                var lfi = or.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

                foreach(var fi in lfi)
                {
                    var eh = fi.GetValue(or) as EventHandler;
                    if (eh != null)
                    {
                        foreach (var del in eh.GetInvocationList())
                        {
                            foreach (var ev in or.GetType().GetEvents())
                            {
                                ev.GetRemoveMethod().Invoke(or, new object[] { del });
                            }
                        }
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            var or = new ObjectRaiser();
            var ol = new ObjectListener(or);

            //This will raise the event
            or.Name = "New Name";
            ol.RemoveHandlers();
            //This will throw an exception because the event has no handler associated
            or.Name = "Weird Name";

            Console.ReadLine();
        }
    }
}

从外部:您不能,因为您无权访问存储处理程序的委托。但是,您可以在
objectRaiser
中添加一个公共
ClearHandlers()
方法,并在任何地方调用它。

我不确定这是否正是您想要的。。。但是在下面的代码中,我们可以使用
Reflection
ObjectListener
中包含的
ObjectRaiser
实例中删除处理程序:

MyEvent = null;
namespace ObjectEvents
{
    class Program
    {
        private class ObjectRaiser
        {
            public event EventHandler PropertyChange;

            private string name;
            public string Name
            {
                get
                {
                    return name;
                }
                set
                {
                    name = value;
                    PropertyChange(this, new EventArgs());
                }
            }
        }

        private class ObjectListener
        {
            private ObjectRaiser or;

            public ObjectListener(ObjectRaiser or)
            {
                this.or = or;
                or.PropertyChange += new EventHandler(PropertyChange);
            }

            public void PropertyChange(object sender, EventArgs e)
            {
                Console.WriteLine("I'm listening!");
            }

            public void RemoveHandlers()
            {
                var lfi = or.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

                foreach(var fi in lfi)
                {
                    var eh = fi.GetValue(or) as EventHandler;
                    if (eh != null)
                    {
                        foreach (var del in eh.GetInvocationList())
                        {
                            foreach (var ev in or.GetType().GetEvents())
                            {
                                ev.GetRemoveMethod().Invoke(or, new object[] { del });
                            }
                        }
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            var or = new ObjectRaiser();
            var ol = new ObjectListener(or);

            //This will raise the event
            or.Name = "New Name";
            ol.RemoveHandlers();
            //This will throw an exception because the event has no handler associated
            or.Name = "Weird Name";

            Console.ReadLine();
        }
    }
}

注意:这是一个非常简单的示例,在实际应用中肯定需要进行重大修改。

基于这个问题,我认为需要删除特定订阅者的所有委托,而不是全部委托。该代码似乎从所有侦听器中删除其事件“PropertyChange”的所有活动处理程序,但我们只希望从具体的objectListener实例中删除所有处理程序。