Como referenciar um evento em C #
Eu tenho a seguinte classe, que tem um evento público chamadoLengthChanged
:
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;
}
Eu gostaria de poder registrar / cancelar o registro de manipuladores para este evento em um método chamadoObserver
, que não sabe nada sobre oDimension
classe. Eu criei dois cenários, nenhum dos quais é realmente satisfatório:
Definir uma interfaceILengthChanged
com oLengthChanged
evento, verifique seDimension
implementaILengthChanged
. Então eu tenho que fornecer uma implementação doObserver
método para cada interface que eu defino. Isso de maneira alguma genérico o suficiente. Eu realmente gostaria de poder simplesmente passar uma referência a umSystem.EventHandler
evento.
UsarSystem.Action<System.EventHandler>
retornos de chamada para registrar e cancelar o registro do manipulador de eventos noObserver
método, assim:
classe Foo {public void Observer (registro System.Action, System.Action cancelado registro) {register (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 seria invocado assim:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (x => dim.LengthChanged += x, x => dim.LengthChanged -= x);
e que, quando executado, acabará de fato conectando oLengthChanged
evento com o manipulador de eventos internoMyEventHandler
. Mas isso não é muito elegante. Eu adoraria poder escrever isso:
Foo foo = ...;
Dimension dim = ...;
foo.Observer (dim.LengthChanged);
mas não tenho ideia de como isso pode ser alcançado. Talvez esteja faltando algo realmente óbvio aqui? Eu acho que algunsdynamic
a magia poderia funcionar, de alguma forma, mas isso não aplicaria a verificação do tipo em tempo de compilação: eu não quero que os usuários deObserver
passar referências a eventos que não satisfaçam aSystem.EventHandler
assinatura de evento.