Как создать делегат метод с 3 параметрами в C # 2? - PullRequest
0 голосов
/ 09 декабря 2010

У меня есть следующий метод:

    private void WriteTrace(object sender, EventArgs e, EventElement eventElement)
    {
    /* ... */
    }

Когда я хочу создать делегат, как это:

Type controlType = control.GetType();
MethodInfo method = typeof(Trace).GetMethod("WriteTrace", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
EventInfo eventInfo = type.Value.GetType().GetEvent("Load");  // for the sample, we suppose the control is a form.
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, method);
eventInfo.AddEventHandler(control, handler);

Строка

Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, this, method);

генерирует ошибку:

Ошибка привязки к целевому методу

Но я не знаю почему?

С уважением,

Флориан

Ответы [ 2 ]

2 голосов
/ 09 декабря 2010

Тип Form.Load равен EventHandler, который имеет только два параметра, а не три. Другими словами, это тоже не удастся:

EventHandler x = new EventHandler(WriteTrace);

Вы не можете создать обработчик событий из метода с неправильным количеством параметров. (На самом деле, есть несколько хитростей в создании таких открытых делегатов, но они здесь не актуальны, ИМО.)

Чего вы действительно пытаетесь достичь? Что бы вы ожидали eventElement в этом случае?

Обратите внимание, что вы можете использовать лямбда-выражения для захвата переменных, например,

EventElement element = ...;
form.Load += (sender, args) => WriteTrace(sender, args, element);

Это тебе вообще помогает? Или вам действительно нужно , чтобы сделать это с отражением?

0 голосов
/ 09 декабря 2010

Короткий ответ: вы не можете напрямую связать обработчик событий с методом с тремя параметрами; метод, который вы передаете, должен точно соответствовать подписи.

Вопрос в том, откуда этот параметр "EventElement"? Как только вы это знаете, вы можете спрятать его в другом объекте, аля:

class HandlerThunk {
  EventElement eventElement;
  Trace receiver;

  // ...

  public void Handler(object sender, EventArgs e) {
    this.receiver.WriteTrace(sender, e, this.eventElement);  
  }
}

... а затем связать его ...

HandlerThunk thunk = ...;

Type controlType = control.GetType();
MethodInfo method = typeof(HandlerThunk).GetMethod("WriteTrace", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
EventInfo eventInfo = type.Value.GetType().GetEvent("Load");  
Delegate handler = Delegate.CreateDelegate(eventInfo.EventHandlerType, thunk, method);
eventInfo.AddEventHandler(control, handler);

И тогда толк перешлет вам событие.

...