2010-06-03 14 views
9

Po prostu zdałem sobie sprawę, że nie w pełni rozumiem, dlaczego w .NET przypisujesz zdarzenia za pomocą symbolu + =.W jaki sposób zdarzenia są przypisane w .NET

wyobraziłem to wczoraj, kiedy potrzebne, aby usunąć zdarzenie i bez zastanowienia robiłem

someobject.onsomeevent += null 

myśląc, że po prostu usunąć zdarzenie miałem wcześniej przypisany.

Po pewnym dochodzenia, zorientowali się, musiałem

someobject.onsomeevent -= someeventmethod; 

Po to zastanawianie się, zdałem sobie sprawę, że nie rozumiem, jak metody zdarzeń są przypisane w .NET.

więc mam kilka pytań:

Pierwsze, to znaczy, że mogę zrobić

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

Jeśli tak, to kiedy onsomeevent występuje będą zarówno oberwać, w podanej kolejności lub jednocześnie?

Ponadto, w jaki sposób określić, które metody zdarzeń są już przypisane do someobject.onsomeevent?

Po drugie, czy istnieje sposób na zapisanie metod zdarzeń w niektórych klasach, usunięcie ich z someobject.onsomeevent i ponowne przypisanie ich po wykonaniu innych procedur, które normalnie wyzwalają zdarzenie?

+1

zamieszania, należy spróbować długi (.NET 1.x) formularz: 'someobject.onsomeevent - = new Eventhandler (someeventmethod);' –

+0

Tak wiele dobrych odpowiedzi! Dziękuje wszystkim! – Matt

Odpowiedz

3

Pierwsze pytanie: Tak, możesz to zrobić, o ile sygnatury metody są zgodne z typem delegata zdarzenia.

Drugie pytanie: Tak, możesz to zrobić. Użyj metody EventTest.GetInvocationList(), aby uzyskać metody zarejestrowane w wydarzeniu. A następnie użyj -= i +=, aby usunąć i ponownie dodać delegatów, odpowiednio. Zobacz poniższy przykład:

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); 
     } 
    } 

usunąłem trywialny Main() -method aby kod był bardziej czytelny.

4

Odnośnie pierwszego pytania: Domyślnie otrzymujesz zachowanie grupowe. Oznacza to, że jeśli masz wiele programów obsługi, domyślnie procedury obsługi zdarzeń będą wywoływane kolejno (chyba że jeden z nich zgłasza wyjątek). Zauważ, że możesz zmienić add (+=) i remove (-=), aby zrobić coś innego niż domyślne zachowanie.

Jon Skeet ma stronę wyjaśniającą delegates and events in C#, którą możesz przeczytać.

2

Odpowiedź brzmi: tak, tak i kolejno w kolejności dodania.

Zdarzenie jest instancją klasy MulticastDelegate. Aby dowiedzieć się, jakie delegacje są przypisane do zdarzenia, wywołaj metodę GetInvocationList zdarzenia. Zobacz: http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx

To da ci szereg delegatów.Można więc wywołać metodę GetInvocationList, aby pobrać istniejące procedury obsługi zdarzeń; następnie wyczyść programy obsługi zdarzeń ze zdarzenia; wykonać jakąś akcję; a następnie ponownie przypisać obsługę do zdarzenia.

2

Delegaci są "multicastowe" w .NET, a zdarzenia są podobnymi do właściwości owijkami. Można uzyskać lepszy undestanding patrząc na imprezie w notacji długo postać:

private EventHandler _handler; 

public event EventHandler MyEvent 
{ 
    add { _handler = (EventHandler)Delegate.Combine(_handler, value); } 
    remove { _handler = (EventHandler)Delegate.Remove(_handler, value); } 
} 

Normalnie będzie pisać wszystko powyższe w 1 linii:

public event EventHandler MyEvent; 

i być kompletny, zdarzenie stanowi listę Invocationlist, którą przetwarza sekwencyjnie po uruchomieniu. Nie ma żadnych gwarancji dotyczących zamówienia.

2

I właśnie na pokrycie jeden bit I nie sądzę, żeby ktoś explictly rozpatrywane, zdarzenia nie wszystko ogień w tym samym czasie - oni ogień w sekwencji ...

Powiązane problemy