2010-12-21 19 views
19

Mam zdarzenie w pętli. Próbuję zapobiec dodaniu tej samej metody do zdarzenia więcej niż raz. Zaimplementowałem akcesory add i remove.-event- może pojawić się tylko po lewej stronie + = lub - =

jednak otrzymuję komunikat o błędzie informujący, że:

ItemsProcessed can only appear on the left hand side of += or -=

Kiedy próbuję zadzwonić do nich, nawet w obrębie tej samej klasy.

ItemsProcessed(this, new EventArgs()); // Produces error 

public event EventHandler ItemsProcessed 
{ 
    add 
    { 
     ItemsProcessed -= value; 
     ItemsProcessed += value; 
    } 
    remove 
    { 
     ItemsProcessed -= value; 
    } 
} 
+3

Wygląda również na to, że utworzyłeś nieskończoną pętlę, uzyskując dostęp do 'ItemsProcessed' w obrębie samych funkcji' ItemsProcessed'. – Gabe

+0

Dla odniesienia, sztuczka 'EventName (args)' wywołuje sztuczkę stosuje się tylko do * zdarzeń polowych *, gdzie niektóre operacje pośrednio przekształcają się w * pole * (nie zdarzenie) w klasie. Muszę powiedzieć "trochę", ponieważ dokładna lista zmieniła się pomiędzy C# 3 i C# 4. –

Odpowiedz

19

z wyraźną razie musisz podać swój własny sklep podkład - albo pole delegata lub coś podobnego EventHandlerList. Aktualny kod jest rekurencyjny. Spróbuj:

private EventHandler itemsProcessed; 
public event EventHandler ItemsProcessed 
{ 
    add 
    { 
     itemsProcessed-= value; 
     itemsProcessed+= value; 
    } 

    remove 
    { 
     itemsProcessed-= value; 
    } 
} 

Wtedy (i odnotowując Ja będąc trochę ostrożny o "zamiar skręcić null" edge-przypadek ponownego gwintowania):

var snapshot = itemsProcessed; 
if(snapshot != null) snapshot(this, EventArgs.Empty); 

Z nowszych wersjach C#, można to uprościć:

itemsProcessed?.Invoke(this, EventArgs.Empty); 
+1

Jedną wadą: Dostępna tylko w klasie –

+2

Dlaczego chcesz uzyskać dostęp do prywatnego obiektu ukrytego poza zajęciami? –

+0

Podklasy, duh. Spraw, aby rzeczy były chronione. – Nyerguds

1

Jaki błąd? Zgaduję, że jego błąd przepełnienia stosu, ponieważ wywołujesz dodawanie i usuwanie na yourserlfie (to samo zdarzenie). Ponadto nie można podnieść zdarzenia ACCESSOR.

Prawidłowym sposobem jest utworzenie kopii zapasowej prywatnego wydarzenia, które zostanie dodane i usunięte z publicznego dostępu, i powinieneś podnieść to prywatne wydarzenie.

Dang, minutę późno.

+1

Nie, nie wie o przepełnieniu stosu, ponieważ jego kod nie kompiluje się. – Gabe

+0

Tak, przestałem o tym myśleć, kiedy odpowiedź Marca została opublikowana ... masz rację. – Euphoric

7

Wygląda na to, że w przypadku jawnego wdrożenia EventHandler nie można odwoływać się do "Właściwość" podczas uruchamiania zdarzenia. Musisz odwołać się do sklepu z zapleczem.

4

Nie mogę powiedzieć z Twojego wpisu, czy próbujesz podnieść wydarzenie z klasy pochodnej, czy nie, ale jedną rzeczą, którą odkryłem jest to, że nie możesz zdefiniować zdarzenia w klasie bazowej, a następnie podnieść to (bezpośrednio) w klasie pochodnej, z jakiegoś powodu, który nie jest dla mnie jeszcze jasny.

Więc definiują chronione funkcje w klasach bazowych, aby podnieść zdarzenia (które są zdefiniowane w tych klasach bazowych), podobnie jak to:

// The signature for a handler of the ProgressStarted event. 
// title: The title/label for a progress dialog/bar. 
// total: The max progress value. 
public delegate void ProgressStartedType(string title, int total); 

// Raised when progress on a potentially long running process is started. 
public event ProgressStartedType ProgressStarted; 

// Used from derived classes to raise ProgressStarted. 
protected void RaiseProgressStarted(string title, int total) { 
    if (ProgressStarted != null) ProgressStarted(title, total); 
} 

Następnie w klasie pochodnej, wzywam RaiseProgressStarted (tytuł, łącznie) zamiast połączenia ProgressStarted (title, total).

Wygląda na to, że jest dość daleko. Być może ktoś inny wie o lepszym sposobie rozwiązania tego problemu.

+0

Właśnie zdałem sobie sprawę, że to jest pięcioletni post. Natknąłem się na problem i zorientowałem się, co się dzieje, więc wysłałem tę odpowiedź. Może ci to pomoże. – Shavais

+0

Heh, znowu miałem ten problem, nie mogłem sobie przypomnieć, co go spowodowało i jak to naprawiłem, i znalazłem własną odpowiedź sprzed 11 miesięcy. To całkiem zabawne. – Shavais

Powiązane problemy