3 Stimmen

C# CS0079 Fehler bei der Kompilierung der Ereignisbehandlung

Ich kann den folgenden Code nicht kompilieren.

Kompilierfehler CS0079 : Das Ereignis 'CustomEvent' kann nur auf der linken Seite von += oder -= erscheinen

if (CustomEvent != null)   //CS0079
    CustomEvent(null, null);  //CS0079

Wie kann ich das zum Laufen bringen?

Meine Implementierung sieht so aus:

public delegate void EventHandler(object sender, EventArgs e);  
public static event EventHandler CustomEvent
{
    add    { CustomEvent += value; }
    remove { CustomEvent -= value; }
 }
private static void Func()
{
    if (CustomEvent != null)      //CS0079
        CustomEvent(null, null);  //CS0079
}

6voto

Marc Gravell Punkte 970173

Deine Bearbeitung zeigt einen rekursiven Aufruf: du definierst ein benutzerdefiniertes Ereignis, was bedeutet, du sollst ein unterstützendes Feld bereitstellen; zum Beispiel:

private static EventHandler customEvent;
public static event EventHandler CustomEvent
{
    add    { customEvent += value; }
    remove { customEvent -= value; }
 }
private static void Func()
{
    var tmp = customEvent;
    if (tmp != null) tmp(null, null);
}

Beachte, dass in Func ich mich auf das Feld (customEvent) beziehe, nicht auf das Ereignis (CustomEvent).

Allerdings ist dies einfacher und besser (thread-sicher) als ein feldähnliches Ereignis:

public static event EventHandler CustomEvent;
private static void Func()
{
    var tmp = CustomEvent;
    if (tmp != null) tmp(null, null);
}

Ein feldähnliches Ereignis verwendet das event Schlüsselwort, ohne die Accessoren: der Compiler fügt für dich eine Menge Boilerplate hinzu (ein unterstützendes Feld und thread-sichere Add/Remove-Implementierungen). Außerdem erlaubt es den Zugriff auf das unterstützende Feld über den Ereignisnamen (vom deklarierenden Typ aus), daher funktioniert die Zeile var tmp = CustomEvent;.

Auch: sei sehr vorsichtig mit statischen Ereignissen; sie sind eine gute Möglichkeit, versehentlich viele Objekte am Leben zu erhalten.

3voto

Marc Gravell Punkte 970173

Du kannst ein Ereignis nur testen/aufrufen, wenn es sich um ein feldähnliches Ereignis handelt, das im aktuellen Typ deklariert ist. Also: Es gibt zwei Szenarien, die dies verursachen könnten:

  1. Es handelt sich nicht um ein feldähnliches Ereignis, sondern hat benutzerdefinierte add/remove Zugriffsmethoden: In diesem Fall weiß nur Ihr benutzerdefinierter Code, wie der Delegat gespeichert ist

  2. Es ist nicht im aktuellen Typ deklariert, sondern in einem Basistyp oder einem unzusammenhängenden Objekt: In diesem Fall müssen Sie den deklarierenden Typ erhalten, um das Ereignis aufzurufen, normalerweise über eine OnCustomEvent Methode. Im Fall eines Basistyps wäre die Konvention, diese Methode als protected virtual zu kennzeichnen, was es den Unterklassen ermöglicht, das Ereignis aufzurufen und in das Ereignis über override einzuhaken


(Kommentare)

Es scheint, als wäre es Fall 1. jedoch verstehe ich nicht, was zu tun ist, um dieses Problem zu lösen.

Wenn Sie benutzerdefinierte add/remove haben, ist es implementierungsspezifisch, wie Sie sie aufrufen (Ich könnte Ihnen mehr sagen, wenn ich die add/remove sehen könnte), aber lassen Sie uns zwei häufige Implementierungen betrachten:

1a: ein untergeordneter Delegat:

private EventHandler someEvent;
public event EventHandler SomeEvent
{
    add { someEvent += value; }
    remove { someEvent -= value; }
}

In diesem Fall wäre die "Aufruf"-Implementierung einfach:

if(someEvent != null) someEvent(this, EventArgs.Empty);

Oder wenn Sie besonders vorsichtig sind:

var handler = someEvent;
if(handler != null) handler(this, EventArgs.Empty);

1b: eine EventHandlerList (verwendet für spärliche Ereignisse):

private static readonly object SomeEventKey = new object();
public event EventHandler SomeEvent
{
    add { Events.AddHandler(SomeEventKey, value); }
    remove { Events.RemoveHandler(SomeEventKey, value); }
}

In diesem Fall wäre die Aufrufimplementierung:

var handler = (EventHandler)Events[SomeEventKey];
if(handler != null) handler(this, EventArgs.Empty);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X