Когда я работаю в F # Interactive, я часто хочу вносить изменения в обработчик событий.Простой вызов функций Subscribe или Add или AddHandler для события приводит к тому, что старое событие продолжает вызываться, что редко является намерением.
Одним из решений является использование возвращаемого идентификатора IDisposable, но для этого требуется отслеживание идентификаторов IDisposables.в вашем собственном коде, который громоздок для исследовательских задач.
Я пытался сделать Dictionary<IEvent,IDisposable>
для вызова Dispose (), когда на то же событие снова подписывается:
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) |> ignore
let w = Window()
w.Show()
//Running this line in FSI a second time onward should Dispose() the previous subscription
subonce w.MouseUp (fun e -> printfn "%A" <| e.GetPosition(w))
К сожалению, как выясняется, F # генерирует новый экземпляр IEvent, поэтому наивно использовать =
или obj.Equals
не обрезает его.
> 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>;}
Существуют ли какие-либо свойства или поля, которые я могу найти вIEvent, который идентифицировал бы это против других экземпляров владельца и против различных событий в этом владельце?