Как события присвоены в.NET

Я просто понял, что не полностью понимаю, почему в.NET Вы присваиваете события с помощью + = символ.

Я понял это вчера, когда я должен был удалить событие и не думая, что я делал

someobject.onsomeevent += null

думая это просто удалило бы событие, которое я ранее присвоил.

После некоторого расследования я выяснил, что имел к

someobject.onsomeevent -= someeventmethod;

После понимания этого я понял, что не понимаю, как методы события присвоены в.NET.

Таким образом, у меня есть несколько вопросов:

Во-первых, делает это означает, что я могу сделать

someobject.onsomeevent += someeventmethod;
someobject.onsomeevent += someeventothermethod;

Если так, когда onsomeevent произойдет, они будут и поражены, и в указанном порядке или одновременно?

Кроме того, как я могу определить то, какие методы события уже присвоены someobject.onsomeevent?

Во-вторых, существует ли способ сохранить методы событий в некотором классе, чтобы удалить их из someobject.onsomeevent и повторно присвоить им после, некоторые другие процедуры, которые обычно инициировали бы событие, завершены?

9
задан Matt 3 June 2010 в 19:33
поделиться

5 ответов

Первый вопрос: Да, вы можете это сделать, если сигнатуры методов совместимы с типом делегата события.

Второй вопрос: да, вы тоже можете это сделать. Используйте 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 () , чтобы сделать код более читабельным.

3
ответ дан 4 December 2019 в 15:12
поделиться

Относительно вашего первого вопроса: по умолчанию вы получаете многоадресное поведение. То есть, если у вас несколько обработчиков, то по умолчанию обработчики событий будут вызываться последовательно (если только один из них не вызовет исключение). Обратите внимание, что вы можете изменить добавить ( + = ) и удалить ( - = ), чтобы сделать что-то отличное от поведения по умолчанию.

У Джона Скита есть страница с описанием делегатов и событий на C # , которую вы, возможно, захотите прочитать.

4
ответ дан 4 December 2019 в 15:12
поделиться

Итак, ответ - да, да и последовательно в порядке добавления.

Событие - это экземпляр класса MulticastDelegate. Чтобы узнать, какие делегаты назначены событию, вызовите метод GetInvocationList для события. См. http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx

Это даст вам массив делегатов. Таким образом, вы можете вызвать GetInvocationList, чтобы получить существующие обработчики событий; затем очистите обработчики событий от события; выполнить какое-то действие; а затем снова назначьте обработчики событию.

2
ответ дан 4 December 2019 в 15:12
поделиться

И просто чтобы скрыть один бит, я не думаю, что кто-то явно имел дело с этим, события не запускаются одновременно - они запускаются последовательно ...

2
ответ дан 4 December 2019 в 15:12
поделиться

В .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, который он обрабатывает последовательно, когда срабатывает. Нет никаких гарантий по поводу заказа.

2
ответ дан 4 December 2019 в 15:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: