Я искал использование выражения lamba, чтобы события могли быть подключены строго типизированным образом, но со слушателем в середине, например. учитывая следующие классыСобытия в лямбда-выражениях - ошибка компилятора C#?
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) { /* ... */ }
}
Событие будет проводная вверх как:
Listener.WireUp<Producer, Consumer>((p, c) => p.MyEvent += c.MyHandler);
Однако это дает ошибку компилятора:
CS0832: An expression tree may not contain an assignment operator
Теперь на первых порах это кажется разумным, особенно после того, как reading the explanation about why expression trees cannot contain assignments , Однако, несмотря на C# синтаксисе +=
не уступка, это вызов метода Producer::add_MyEvent
, как мы можем видеть из КСС, который производится, если мы просто подключить событие нормально:
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)
Таким образом, мне кажется, что это ошибка компилятора, поскольку она жалуется на то, что присваивания не разрешены, но нет назначения, просто вызов метода. Или я что-то упускаю ...?
Edit:
Пожалуйста, обратите внимание, что вопрос "Является ли это поведение компилятора ошибка?". Извините, если я не понял, о чем я просил.
Edit 2
После прочтения ответа Inferis', где он говорит, что „в этой точке + = считается назначение“ это делает какой-то смысл, потому что в этот момент компилятор, возможно, не знайте, что это превратится в CIL.
Однако я не разрешается писать явный вид вызова метода:
Listener.WireUp<Producer, Consumer>(
(p, c) => p.add_MyEvent(new EventHandler(c.MyHandler)));
Дает:
CS0571: 'Producer.MyEvent.add': cannot explicitly call operator or accessor
Так что, я думаю, вопрос сводится к тому, что +=
на самом деле означает в контексте События C#. Означает ли это, что «вызывает метод добавления для этого события» или это означает «добавить к этому событию пока неопределенным образом». Если это первый, то мне кажется, что это ошибка компилятора, тогда как если это последняя, то это несколько неинтуитивно, но, возможно, не ошибка. Мысли?
+ = означает «вызывать средство доступа к событию для данного события». Я думаю, что это не ошибка как таковая, а немного раздражающее и, возможно, ненужное ограничение. –