gpt4 book ai didi

f# - 有没有办法识别 F# 中的 CLR 事件实例?

转载 作者:行者123 更新时间:2023-12-02 17:43:44 25 4
gpt4 key购买 nike

当我在 F# Interactive 中工作时,我经常想要对事件处理程序进行更改。简单地对事件调用 Subscribe 或 Add 或 AddHandler 函数会导致旧事件继续被调用,这很少是意图。

一种解决方案是使用它返回的 IDisposable,但这需要在您自己的代码中跟踪 IDisposable,这对于探索性任务来说很麻烦。

我尝试过制作 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 中找到任何属性或字段,这些属性或字段可以根据所有者的其他实例以及该所有者中的不同事件来识别它吗?

最佳答案

不完全是问题的答案,但我想不出您需要识别事件实例的许多其他场景,所以也许这已经足够好了:

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 或调整 IDisposableHandler 对象。

关于f# - 有没有办法识别 F# 中的 CLR 事件实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54858203/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com