Можно ли вызвать событие на объекте, извне этого объекта, без пользовательской функции - PullRequest
4 голосов
/ 05 августа 2009
public class a
{
   public event eventhandler test;
   public void  RaiseTest(){//fire test}
}

Можно ли поднять тест для этого класса, вне этого класса, без вызова метода?

Обычно у меня есть большое количество событий, которые должны быть вызваны на основе внешнего источника, и я не хочу создавать функцию Raise () для каждого из них.

Можно ли создать универсальный Raise (), который принимает событие, которое будет вызвано в качестве параметра? следовательно, он все равно будет вызываться из класса?

Ответы [ 2 ]

5 голосов
/ 05 августа 2009

Вы можете сделать это через Reflection, но это менее чем очевидно. Если вы объявите событие в C #, в класс будет добавлено поле с именем события + «Событие». Если вы вызовете GetValue для поля, он вернет экземпляр MulticastDelegate.

Получив MulticastDelegate, вы можете получить список вызовов и вызвать каждого участника по очереди:

EventArgs e = new EventArgs(myClassInstance);  // Create appropriate EventArgs

MulticastDelegate eventDelagate = 
    this.GetType().GetField(theEventName + "Event",
    System.Reflection.BindingFlags.Instance | 
    System.Reflection.BindingFlags.NonPublic).GetValue(myClassInstance) as MulticastDelegate;

Delegate[] delegates = eventDelagate.GetInvocationList();
foreach (Delegate del in delegates) {  
      del.Method.Invoke(del.Target, new object[] { myClassInstance, e }); 
}

Обратите внимание, что для этого необходимо получить поле NonPublic из экземпляра, поэтому оно будет работать только с полным доверием и очень ограничено.

Можно ли создать универсальный Raise (), который принимает событие, которое будет вызвано в качестве параметра? следовательно, он все равно будет вызываться из класса?

Да. Было бы довольно легко изменить приведенный выше код, чтобы сделать это. Просто замените «myClassInstance» этим. Это на самом деле также позволит правильно работать с полным доверием, поскольку NonPublic BindingFlag больше не будет проблемой.

1 голос
/ 05 августа 2009

Можно ли поднять тест для этого класса, вне этого класса, без вызова метода?

Краткий ответ: нет.

Только класс, объявляющий событие, может поднять его

Можно ли создать универсальный Raise (), который принимает событие, которое будет вызвано в качестве параметра? следовательно, он все равно будет вызываться из класса?

Я так не думаю, по крайней мере, нелегко ... Даже с помощью отражения нет EventInfo.Invoke метода. AFAIK, единственный способ поднять событие статически из класса

РЕДАКТИРОВАТЬ: на самом деле это может быть сделано (см. Ответ Рида), но с ограничением, что приложение должно работать в полном доверии.

...