【问题标题】:add/remove c# event handlers with a single method使用单个方法添加/删除 c# 事件处理程序
【发布时间】:2017-06-23 14:24:11
【问题描述】:

有没有办法通过传递运算符 += 和 -= 作为参数在 c# 中添加和删除事件处理程序,这样一个方法就可以做到?

我试图避免重复:

AttachHandlers()
{
   event1 += handler1;
   event2 += handler2;
   // etc...
}

DetachHandlers()
{
   event1 -= handler1;
   event2 -= handler2;
   // etc...
}

AttachDetachHandlers(bool attach)
{
   if (attach)
   {
     event1 += handler1;
     event2 += handler2;
   // etc...
   }
   else
   {
     event1 -= handler1;
     event2 -= handler2;
   }
}

相反,我想写这样的东西:

AttachDetachHandlers(operator addRemove)
{
  addRemove(event1, handler1);
  addRemove(event2, handler2);
  // etc...
}

与类似的东西一起使用:

AttachDetachHandlers(+=);

理想情况下,它应该与具有不同签名的事件和处理程序一起使用(就像 += & -= do)。

【问题讨论】:

  • 为什么不使用基于布尔值的 if 语句?
  • @Juan:因为它仍然是重复的(在问题中添加了一个示例)
  • @Sinatr 我不想在附加处理程序后立即分离它们。我想要一个函数来替换 AttachHandlers() 和 DetachHandlers()

标签: c# events delegates operators eventhandler


【解决方案1】:

你可以试试这个:

    public static void Attach<T>(ref EventHandler<T> a, EventHandler<T> b)
    {
        a += b;
    }

    public static void Detach<T>(ref EventHandler<T> a, EventHandler<T> b)
    {
        a -= b;
    }

    public static void AttachDetachHandlers<T>(Action<ref EventHandler<T>, EventHandler<T>> op)
    {
        op(ref event1, handler1);
        op(ref event2, handler2);
        //etc...
    }

然后像这样使用:

        AttachDetachHandlers<int>(Attach);
        //...
        AttachDetachHandlers<int>(Detach);

【讨论】:

    【解决方案2】:

    使用此示例代码。但请注意,事件处理程序的签名必须相同。

    class Program
    {
        delegate void dlgHandlerOperation<T>(ref EventHandler<T> Event, EventHandler<T> Handler);
    
        static void SetHandler<T>(ref EventHandler<T> Event, EventHandler<T> Handler) { Event += Handler; }
        static void UnsetHandler<T>(ref EventHandler<T> Event, EventHandler<T> Handler) { Event -= Handler; }
    
        static void SetAll(dlgHandlerOperation<int> Op)
        {
            Op(ref ev, foo);
            Op(ref ev, bar);
        }
    
        static event EventHandler<int> ev;
    
        static void Main(string[] args)
        {
            SetAll(SetHandler);
            ev?.Invoke(null, 5);
    
            SetAll(UnsetHandler);
            ev?.Invoke(null, 6);
        }
    
        static void foo(object sender, int e) { Console.WriteLine("foo => " + e); }
        static void bar(object sender, int e) { Console.WriteLine("bar => " + e); }
    }
    

    【讨论】:

      猜你喜欢
      • 2016-06-06
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      • 2022-01-14
      • 2012-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多