Ich schaute auf die Verwendung eines Lamba-Ausdruckes, um zu ermöglichen, dass Ereignisse stark typisiert verdrahtet werden, aber mit einem Hörer in der Mitte, z. die folgenden Klassen gegebenEreignisse in Lambda-Ausdrücken - C# -Compiler-Fehler?
class Producer
{
public event EventHandler MyEvent;
}
class Consumer
{
public void MyHandler(object sender, EventArgs e) { /* ... */ }
}
class Listener
{
public static void WireUp<TProducer, TConsumer>(
Expression<Action<TProducer, TConsumer>> expr) { /* ... */ }
}
Ein Ereignis wie verdrahtet werden würde:
Listener.WireUp<Producer, Consumer>((p, c) => p.MyEvent += c.MyHandler);
jedoch ergibt dies einen Compiler-Fehler:
CS0832: An expression tree may not contain an assignment operator
nun zunächst das scheint vernünftig, vor allem nach reading the explanation about why expression trees cannot contain assignments . trotz der C# Syntax, jedoch ist die +=
keine Zuordnung, ist es ein Aufruf der Producer::add_MyEvent
Verfahren, wie wir aus der CIL sehen können, die erzeugt wird, wenn wir in der Regel nur das Ereignis verdrahten:
L_0001: newobj instance void LambdaEvents.Producer::.ctor()
L_0007: newobj instance void LambdaEvents.Consumer::.ctor()
L_000f: ldftn instance void LambdaEvents.Consumer::MyHandler(object, class [mscorlib]System.EventArgs)
L_0015: newobj instance void [mscorlib]System.EventHandler::.ctor(object, native int)
L_001a: callvirt instance void LambdaEvents.Producer::add_MyEvent(class [mscorlib]System.EventHandler)
So sieht es für mich aus, als wäre dies ein Compiler-Fehler, da er sich darüber beschwert, dass Zuweisungen nicht erlaubt sind, aber es findet keine Zuweisung statt, nur ein Methodenaufruf. Oder vermisse ich etwas ...?
Edit:
Bitte beachten Sie, dass sich die Frage: "Ist dieses Verhalten ein Compiler Fehler?". Entschuldigung, wenn ich nicht klar darüber bin, was ich gefragt habe.
Edit 2
Nach Antwort Inferis lesen, wo er sagt, ‚an diesem Punkt die + = gilt als Zuordnung‘ dies hat einige sinnvoll, da an dieser Stelle der Compiler wohl nicht der Fall ist weiß, dass es in CIL verwandelt wird.
aber ich bin nicht die explizite Methodenaufruf Form zu schreiben erlaubt:
Listener.WireUp<Producer, Consumer>(
(p, c) => p.add_MyEvent(new EventHandler(c.MyHandler)));
Gibt:
CS0571: 'Producer.MyEvent.add': cannot explicitly call operator or accessor
Also, ich denke, die Frage zu kommt auf, was +=
bedeutet tatsächlich im Zusammenhang mit der C# -Ereignisse. Bedeutet es "rufe die Add-Methode für dieses Event auf" oder bedeutet "add to this event in noch nicht definierter Weise". Wenn es das erstere ist, dann scheint mir das ein Compiler-Bug zu sein, während es, wenn es das letztere ist, etwas unintuitiv ist, aber wohl kein Bug. Gedanken?
+ = bedeutet "den Ereignisaccessor für das angegebene Ereignis aufrufen". Ich denke, es ist kein Fehler, sondern eine leicht nervige und wohl unnötige Einschränkung. –