Код: Выделить всё
class Producer
{
public event EventHandler MyEvent;
}
class Consumer
{
public void MyHandler(object sender, EventArgs e) { /* ... */ }
}
class Listener
{
public static void WireUp(
Expression expr) { /* ... */ }
}
Код: Выделить всё
Listener.WireUp
((p, c) => p.MyEvent += c.MyHandler);
CS0832: Дерево выражений может не содержать оператора присваивания
На первый взгляд это кажется разумным, особенно после прочтения объяснения о том, почему деревья выражений не могут содержать присваивания. Однако, несмотря на синтаксис C#, += не является присваиванием, а является вызовом метода Producer::add_MyEvent, как мы можем видеть из CIL, который создается, если мы просто подключите событие как обычно:
Код: Выделить всё
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)
Редактировать:
Обратите внимание. что вопрос: «Является ли такое поведение ошибкой компилятора?». Извините, если я не совсем ясно выразил вопрос.
Изменить 2
После прочтения ответа Inferis, где он говорит, что «в этот момент += считается присваиванием», это имеет некоторый смысл, потому что в этот момент компилятор, возможно, не знает, что он будет преобразован в CIL.
Однако мне не разрешено писать форму явного вызова метода:
Код: Выделить всё
Listener.WireUp
(
(p, c) => p.add_MyEvent(new EventHandler(c.MyHandler)));
CS0571: «Producer.MyEvent.add»: невозможно явно вызвать оператор или метод доступа
Итак, я думаю, вопрос сводится к тому, что на самом деле означает += в контексте События C#. Означает ли это «вызвать метод добавления для этого события» или означает «добавить к этому событию еще неопределенным способом». Если первое, то мне кажется, что это ошибка компилятора, а если второе, то это несколько не интуитивно понятно, но, возможно, это не ошибка. Мысли?
Подробнее здесь: https://stackoverflow.com/questions/564 ... mpiler-bug