When I'm working in F# Interactive, I often want to make changes to an event handler. Simply calling the Subscribe or Add or AddHandler functions on an event causes the old event to continue being called, which is rarely the intention.
One solution is to use the IDisposable that it returns, but that requires tracking the IDisposables in your own code, which is cumbersome for exploratory tasks.
I've tried making a Dictionary<IEvent,IDisposable>
to call Dispose() when the same event is subscribed to again:
let events = Dictionary<obj, IDisposable>()let subonce (e:IEvent<'h,'e>) (handler: 'e -> unit) = if events.ContainsKey e then events.[e].Dispose() events.Remove e |> ignore let d = e.Subscribe handler events.Add (e,d) |> ignorelet w = Window()w.Show()//Running this line in FSI a second time onward should Dispose() the previous subscriptionsubonce w.MouseUp (fun e -> printfn "%A"<| e.GetPosition(w))
Unfortunately, as it turns out, F# generates a new IEvent instance, so naively using =
or obj.Equals
doesn't cut it.
> w.MouseUp;;val it : IEvent<Input.MouseButtonEventHandler,Input.MouseButtonEventArgs> =<published event> {addHandler = <fun:it@5-70>; createHandler = <fun:it@5-72>; removeHandler = <fun:it@5-71>;}> w.MouseUp;;val it : IEvent<Input.MouseButtonEventHandler,Input.MouseButtonEventArgs> =<published event> {addHandler = <fun:it@6-74>; //note that these functions are of a different anonymous instance createHandler = <fun:it@6-76>; removeHandler = <fun:it@6-75>;}
Are there any properties or fields I can find within an IEvent that would identify it against other instances of the owner and against different events in that owner?