C# Generics won't allow Delegate Type Constraints

前端 未结 8 1276
别跟我提以往
别跟我提以往 2020-11-28 08:01

Is it possible to define a class in C# such that

class GenericCollection : SomeBaseCollection where T : Delegate

I couldn

8条回答
  •  清歌不尽
    2020-11-28 08:32

    I came across a situation where I needed to deal with a Delegate internally but I wanted a generic constraint. Specifically, I wanted to add an event handler using reflection, but I wanted to use a generic argument for the delegate. The code below does NOT work, since "Handler" is a type variable, and the compiler won't cast Handler to Delegate:

    public void AddHandler(Control c, string eventName, Handler d) {
      c.GetType().GetEvent(eventName).AddEventHandler(c, (Delegate) d);
    }
    

    However, you can pass a function that does the conversion for you. convert takes a Handler argument and returns a Delegate:

    public void AddHandler(Control c, string eventName, 
                      Func convert, Handler d) {
          c.GetType().GetEvent(eventName).AddEventHandler(c, convert(d));
    }
    

    Now the compiler is happy. Calling the method is easy. For example, attaching to the KeyPress event on a Windows Forms control:

    AddHandler(someControl, 
               "KeyPress", 
               (h) => (KeyEventHandler) h,
               SomeControl_KeyPress);
    

    where SomeControl_KeyPress is the event target. The key is the converter lambda - it does no work, but it convinces the compiler you gave it a valid delegate.

    (Begin 280Z28) @Justin: Why not use this?

    public void AddHandler(Control c, string eventName, Handler d) { 
      c.GetType().GetEvent(eventName).AddEventHandler(c, d as Delegate); 
    } 
    

    (End 280Z28)

提交回复
热议问题