Estaba buscando usar una expresión lamba para permitir que los eventos se cableen de una manera fuertemente tipada, pero con un oyente en el medio, p. teniendo en cuenta las siguientes clasesEventos en expresiones lambda - ¿Error del compilador 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) { /* ... */ }
}
Un evento se cablea como:
Listener.WireUp<Producer, Consumer>((p, c) => p.MyEvent += c.MyHandler);
Sin embargo, esto da un error del compilador:
CS0832: An expression tree may not contain an assignment operator
Ahora al principio esto parece razonable, sobre todo después de reading the explanation about why expression trees cannot contain assignments . Sin embargo, a pesar de la sintaxis de C#, la +=
no es una asignación, se trata de una llamada al método Producer::add_MyEvent
, como podemos ver en la CIL que se produce si sólo cablear el evento hasta normalmente:
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)
Me parece que esto es un error del compilador, ya que se queja de que no se permiten las asignaciones, pero no hay ninguna asignación, solo una llamada a un método. O me estoy perdiendo algo...?
Editar:
Tenga en cuenta que la pregunta es "¿Es este comportamiento un error del compilador?". Lo siento si no tenía claro lo que estaba preguntando.
Editar 2
Después de leer la respuesta Inferis', donde dice que 'en ese momento el + = se considera que la asignación' esto hace que tenga algún sentido, porque en este momento el compilador no lo hace podría decirse Sé que se convertirá en CIL.
Sin embargo no se me permite escribir la forma llamada de método explícito:
Listener.WireUp<Producer, Consumer>(
(p, c) => p.add_MyEvent(new EventHandler(c.MyHandler)));
Da:
CS0571: 'Producer.MyEvent.add': cannot explicitly call operator or accessor
tanto, creo que la cuestión se reduce a lo +=
realmente significa en el contexto de C# eventos. Significa "llamar al método de agregar para este evento" o significa "agregar a este evento de una manera aún no definida". Si es el primero, entonces me parece que es un error del compilador, mientras que si es el último, entonces no es intuitivo, pero podría decirse que no es un error. ¿Pensamientos?
+ = significa "llamar al acceso del evento para el evento dado". Creo que no es un error como tal, sino una restricción ligeramente molesta y posiblemente innecesaria. –