tengo la siguiente clase, que tiene un evento público llamado LengthChanged
:Cómo hacer referencia a un evento en C#
class Dimension
{
public int Length
{
get
{
return this.length;
}
set
{
if (this.length != value)
{
this.length = value;
this.OnLengthChanged();
}
}
protected virtual void OnLengthChanged()
{
var handler = this.LengthChanged;
if (handler != null)
{
handler (this, System.EventArgs.Empty);
}
}
public event System.EventHandler LengthChanged;
private int length;
}
me gustaría ser capaz de registrar/manipuladores de anular el registro de este evento en un método llamado Observer
, que no sabe nada sobre la clase Dimension
. He llegado con dos escenarios, ninguno de los cuales son realmente satisfactorio:
definir una interfaz
ILengthChanged
con el eventoLengthChanged
, a continuación, asegúreseDimension
implementaILengthChanged
. Entonces, tengo que proporcionar una implementación del métodoObserver
para cada interfaz que defina. Esto de ninguna manera lo suficientemente genérico. Realmente me gustaría poder pasar una referencia al eventoSystem.EventHandler
.Use
System.Action<System.EventHandler>
devoluciones de llamada para registrar y anular el registro del controlador de eventos en el métodoObserver
, al igual que:clase Foo { Observador public void (registro System.Action, anular el registro System.Action) { registro (this.MyEventHandler);
// keep track of the unregister callback, so that we can unregister // our event handler later on, if needed... } private void MyEventHandler(object sender, System.EventArgs e) { ... }
}
que luego se invoca así:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);
y que, cuando se ejecuta, de hecho va a terminar el cableado del evento LengthChanged
con el controlador de eventos internos MyEventHandler
. Pero esto no es muy elegante. Me hubiera encantado poder escribir esto en su lugar:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
pero no tengo idea de cómo se podría lograr esto. Tal vez me estoy perdiendo algo realmente obvio aquí? Supongo que un poco de magia dynamic
podría hacer el truco, de alguna manera, pero esto no haría cumplir la verificación de tipos de tiempo de compilación: No quiero que los usuarios de Observer
pasen referencias a eventos que no satisfacen la firma de evento System.EventHandler
.
Si la gente como Erik Meijer no fueron capaces de llegar a soluciones más limpias, me sospecha que, de hecho, no hay otra manera de hacerlo. Eso es triste ... Gracias por su respuesta rápida, Jon. –