add/remove 具有单一方法的 c# 事件处理程序

add/remove c# event handlers with a single method

有没有办法通过将运算符 += 和 -= 作为参数传递来在 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)。

你可以试试这个:

    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);

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

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); }
}