Esto es lo que quiero decir. Supongamos que estoy trabajando con una API que expone eventos, pero estos eventos no siguen la firma estándar EventHandler
o EventHandler<TEventArgs>
. Un evento podría tener este aspecto, por ejemplo:¿Cómo puedo obtener un IObservable <T> en Rx de un evento "no estándar"?
Public Event Update(ByVal sender As BaseSubscription, ByVal e As BaseEvent)
Ahora, por lo general, si quiero tener una IObservable<TEventArgs>
de un evento, sólo puede hacer esto:
Dim updates = Observable.FromEvent(Of UpdateEventArgs)(_
target:=updateSource, _
eventName:="Update" _
)
pero esto no significa trabajo, porque el evento Update
no es un EventHandler<UpdateEventArgs>
- de hecho, hay es no UpdateEventArgs
- básicamente es solo lo suyo.
Obviamente, podría definir mi propios procedentes clase de EventArgs
(es decir, UpdateEventArgs
), escribir otra clase para envolver el objeto que proporciona el evento Update
, dar la clase contenedora su propio evento Update
que es una EventHandler<UpdateEventArgs>
, y obtenga IObservable<UpdateEventArgs>
de que. Pero esa es una cantidad molesta de trabajo.
¿Hay alguna forma de crear un IObservable<[something]>
a partir de un evento "no estándar" como este, o no tengo suerte?
ACTUALIZACIÓN: A partir de la respuesta de Jon Skeet, me dio un codazo en la dirección de la siguiente sobrecarga del Observable.FromEvent
:
Function FromEvent(Of TDelegate, TEventArgs As EventArgs)(_
conversion As Func(Of EventHandler(Of TEventArgs), TDelegate), _
addHandler As Action(Of TDelegate), _
removeHandler As Action(Of TDelegate) _
) As IObservable(Of IEvent(Of TEventArgs))
tengo que admitir, sin embargo, estoy teniendo problemas para envolver mi cabeza alrededor de esa parte Func(Of EventHandler(Of TEventArgs), TDelegate)
. Me parece al revés (?). Obviamente, hay algo que me falta ...
De todos modos, en caso de que ayuda, yo creo esto es lo que el código C# equivalentes se vería así (Voy a ser honesto: No estoy seguro . a pesar de que este generalmente prefiero C# yo, este código es la obra de uno de mis colegas, que escribe principalmente en VB.NET, y VB.NET permite múltiples sintaxis para los eventos que declaran):
// notice: not an EventHandler<TEventArgs>
public delegate void UpdateEventHandler(BaseSubscription sender, BaseEvent e);
// not 100% sure why he did it this way
public event UpdateEventHandler Update;
el La parte difícil aquí es que parece que algún tipo de clase derivado de EventArgs
es necesario, sin importar qué. En la API con la que estoy trabajando, no hay tal clase. Entonces, como mínimo, tendré que escribir uno. Pero eso debería ser bastante trivial (básicamente una propiedad: BaseEvent
).
Al final, estoy suponiendo que el código necesario para esta sobrecarga sería algo como esto en C#:
var updates = Observable.FromEvent<UpdateEventHandler, UpdateEventArgs>(
// conversion (Func<EventHandler<UpdateEventArgs>, UpdateEventHandler>)
handler => (sender, e) => handler(sender, new UpdateEventArgs(e)),
// addHandler (Action<UpdateEventHandler>)
handler => updateSource.Update += handler,
// removeHandler (Action<UpdateEventHandler>)
handler => updateSource.Update -= handler
);
En primer lugar: qué me he entendido bien? En segundo lugar: ¿tengo razón al decir que al usar VB 9, realmente no hay forma de lograr lo anterior sin escribir mis propios métodos?
Casi me parece que estoy abordando este problema desde el ángulo totalmente equivocado para empezar. Pero realmente no estoy seguro
Su ejemplo de C# era correcto, la forma de hacerlo en VB es la misma, pero la sintaxis es un poco más desordenada. Vea el ejemplo que publiqué a continuación para referencia futura. –