Есть ли способ идентифицировать экземпляры событий CLR в F #? - PullRequest
0 голосов
/ 25 февраля 2019

Когда я работаю в 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, который идентифицировал бы это против других экземпляров владельца и против различных событий в этом владельце?

1 Ответ

0 голосов
/ 26 февраля 2019

Не совсем ответ на вопрос, но я не могу придумать много других сценариев, в которых вам нужно было бы идентифицировать экземпляр события, поэтому, возможно, это достаточно хорошо:

type OneHandler<'e> = { mutable h : 'e -> unit }
let onehandler (e:IEvent<'h,'e>) =
    let h = { h = fun _ -> () }
    e.Subscribe(fun e -> h.h e) |> ignore
    h

let w = Window()
let wmouseup = onehandler w.MouseUp

wmouseup.h <- (fun e -> printfn "%A" <| e.GetPosition(w))

ЭтоТаким образом, оценивая только присвоение wmouseup.h, мы можем изменить обработчик событий, не перезапуская объекты w или juggle IDisposable или Handler.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...