如何推断通用委托类型的方法签名以调用委托列表

时间:2019-04-05 17:07:26

标签: c#

我试图创建一个事件处理程序,该事件处理程序将循环遍历相同类型的代表列表,并在需要时调用它们。我最终想要的是一个“主”处理程序,该处理程序控制调用哪个子处理程序(这是用于实现默认事件处理的嵌套状态机,因此,如果事件在嵌套级别中得到处理,则阻止其传播到更高级别。 )

我最简单的解决方案是仅订阅“最深”事件处理程序。但这不是我真正想要的行为,我希望该处理程序的主体说出它是否实际上“处理”了该事件,如果没有,则调用下一个上层。

所以我的第二种方法是只让一个实际的事件订户。反过来,它会逐步浏览代表列表,并使用修改后的方法签名调用它们,如果方法处理了事件,则返回一个布尔值。

我的.NET事件定义:

        public static event SensorChangeHandler SensorChangedEvent;
        public delegate void SensorChangeHandler(bool triggered);
        public static void TriggerSensorChange(bool triggered)
        {
            SensorChangedEvent?.Invoke(triggered);
        }

在我的“主处理程序”课程中:

        List<Func<bool, bool>> myChildHandlers = new List<Func<bool, bool>>();
        public void AddChildHandler(Func<bool, bool> childHandler)
        {
            myChildHandlers.Add(childHandler);
        }

        public SensorChangeHandler GetMasterHandler()
        {
            return (bool sensorTriggered) =>
            {
                foreach(var handler in myChildHandlers)
                {
                    if(handler(sensorTriggered))
                    {
                        // event handled, so break out of loop
                        return;
                    }
                }
            };
        }

在我的通话课上:

            MasterHandler sensorChangedMaster = new MasterHandler();
            sensorChangedMaster.AddChildHandler((bool triggered) =>
            {
                if(triggered)
                {
                    // do some stuff
                    return true;
                }
                else
                {
                    // not handled
                    return false;
                }
            })
            // the actual .NET event subscriber
            SensorChangedEvent += sensorChangedMaster.GetMasterHandler();

如果我要做的只是响应SensorChanged事件,则此方法很好。但是我想使这种模式通用,即

MasterHandler sensorChanged = new MasterHandler<SensorChangeHandler>();            

public class MasterHandler<THandler> {
...
        List<Func<bool, THandlerArgs>> myChildHandlers = new List<Func<bool, THandlerArgs>>();
        public void AddChildHandler(Func<bool, THandlerArgs> childHandler)
        {
            myChildHandlers.Add(childHandler);
        }

        public THandler GetMasterHandler()
        {
            return (THandlerArgs args) =>
            {
                foreach(var handler in myChildHandlers)
                {
                    if(handler(args))
                    {
                        return;
                    }
                }
            };
        }
}

我是使用泛型和反射的新手,而且我不清楚如何获取委托参数并将其传递给处理程序。任何建议将不胜感激!

1 个答案:

答案 0 :(得分:1)

当您有一个发布者和多个订阅者时,允许订阅者之间进行通信的标准方法是在Handled类中提供布尔属性SensorChangedEventArgs。这样,一个订阅者将处理事件,将Handled属性设置为true,其他所有订阅者将看到事件已处理并退出,而无需执行其他任何操作。

在您的情况下,您似乎有多个发布者和一个订阅者,因此情况有所不同。老实说,您的体系结构让我感到困惑。