Я просто понял, что не полностью понимаю, почему в.NET Вы присваиваете события с помощью + = символ.
Я понял это вчера, когда я должен был удалить событие и не думая, что я делал
someobject.onsomeevent += null
думая это просто удалило бы событие, которое я ранее присвоил.
После некоторого расследования я выяснил, что имел к
someobject.onsomeevent -= someeventmethod;
После понимания этого я понял, что не понимаю, как методы события присвоены в.NET.
Таким образом, у меня есть несколько вопросов:
Во-первых, делает это означает, что я могу сделать
someobject.onsomeevent += someeventmethod;
someobject.onsomeevent += someeventothermethod;
Если так, когда onsomeevent произойдет, они будут и поражены, и в указанном порядке или одновременно?
Кроме того, как я могу определить то, какие методы события уже присвоены someobject.onsomeevent?
Во-вторых, существует ли способ сохранить методы событий в некотором классе, чтобы удалить их из someobject.onsomeevent и повторно присвоить им после, некоторые другие процедуры, которые обычно инициировали бы событие, завершены?
Первый вопрос: Да, вы можете это сделать, если сигнатуры методов совместимы с типом делегата события.
Второй вопрос: да, вы тоже можете это сделать. Используйте EventTest.GetInvocationList ()
, чтобы получить методы, зарегистрированные для вашего события. Затем используйте - =
и + =
для удаления и повторного добавления делегатов соответственно. См. Пример ниже:
public class Test
{
public event EventHandler EventTest = delegate { };
public void Method()
{
//get registered event handlers
Delegate[] invocationList = EventTest.GetInvocationList();
//remove them
foreach (Delegate d in invocationList)
{
EventTest -= (EventHandler)d;
}
//this method won't trigger anything, because
//invocation list is empty
Method2();
//re-add event handlers
foreach (Delegate d in invocationList)
{
EventTest += (EventHandler)d;
}
}
public void Method2()
{
if(EvenTest != null)
EventTest(this, EventArgs.Empty);
}
}
Я удалил тривиальный метод Main ()
, чтобы сделать код более читабельным.
Относительно вашего первого вопроса: по умолчанию вы получаете многоадресное поведение. То есть, если у вас несколько обработчиков, то по умолчанию обработчики событий будут вызываться последовательно (если только один из них не вызовет исключение). Обратите внимание, что вы можете изменить добавить
( + =
) и удалить
( - =
), чтобы сделать что-то отличное от поведения по умолчанию.
У Джона Скита есть страница с описанием делегатов и событий на C # , которую вы, возможно, захотите прочитать.
Итак, ответ - да, да и последовательно в порядке добавления.
Событие - это экземпляр класса MulticastDelegate. Чтобы узнать, какие делегаты назначены событию, вызовите метод GetInvocationList для события. См. http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx
Это даст вам массив делегатов. Таким образом, вы можете вызвать GetInvocationList, чтобы получить существующие обработчики событий; затем очистите обработчики событий от события; выполнить какое-то действие; а затем снова назначьте обработчики событию.
И просто чтобы скрыть один бит, я не думаю, что кто-то явно имел дело с этим, события не запускаются одновременно - они запускаются последовательно ...
В .NET делегаты являются "многоадресными", а события - подобными свойствам оболочками. Вы можете лучше понять, глядя на событие в длинной нотации:
private EventHandler _handler;
public event EventHandler MyEvent
{
add { _handler = (EventHandler)Delegate.Combine(_handler, value); }
remove { _handler = (EventHandler)Delegate.Remove(_handler, value); }
}
Обычно вы пишете все вышеперечисленное в одной строке:
public event EventHandler MyEvent;
И для полноты, событие представляет собой Invocationlist, который он обрабатывает последовательно, когда срабатывает. Нет никаких гарантий по поводу заказа.