所以,我有一个我想在事件触发器上执行的函数,但我想稍后删除它。我该怎么做?我知道F#事件具有Add
方法,该方法将函数添加为处理程序,但您无法删除此函数。我理解,但我找不到如何创建任何委托! (嗯,是 type Foo = delegate of type1 -> type2
,但我不明白它的用法......)
编辑:这是一个更清晰的例子,我想做什么,在代码中:
// Define and publish event
let _someEvent = new Event<string>()
let SomeEvent = someEvent.Publish
// Normally, I'd do this to use it:
SomeEvent.Add (fun arg -> printfn "Argument: %s" arg)
// Trigger the event
someEvent.Trigger "Hello world"
但我的问题是我想在某个时候删除这个钩子。我知道这可能与代表有关......只是不知道如何做到这一点。
答案 0 :(得分:7)
另一种选择是使用Subscribe方法并使用Dispose取消订阅:
// Define and publish event
let someEvent = new Event<string>()
let SomeEvent = someEvent.Publish
// Subscribe to event
let subscription =
SomeEvent.Subscribe (fun arg -> printfn "Argument: %s" arg)
// Trigger the event
someEvent.Trigger "Hello world"
// Unsubscribe
subscription.Dispose()
答案 1 :(得分:5)
是的,只需使用处理程序。
// Define and publish event
let _someEvent = new Event<string>()
let SomeEvent = _someEvent.Publish
// wrap function in handler
let handler = Handler<string>(fun _ arg -> printfn "Argument: %s" arg)
// add
SomeEvent.AddHandler handler
// remove
SomeEvent.RemoveHandler handler
答案 2 :(得分:3)
您可以在F#中创建委托,就像创建任何其他对象一样。只需将函数传递给它的构造函数即可。您还可以使用RemoveHandler
从任何.Net语言中删除事件中的处理程序。您需要确保将其传递给首先添加的相同委托。
此示例(您可以在FSI中运行)创建一个填充蓝色表单的PaintEventHandler
,并将其添加到表单的Paint
事件中。然后设置窗体上的按钮以从事件中删除绘制处理程序,并强制窗体重绘。
open System
open System.Drawing
open System.Windows.Forms
let form = new Form()
let paintHandler =
PaintEventHandler( // The function is passed to the delegate constructor.
fun sender e ->
e.Graphics.Clear Color.CornflowerBlue
)
form.Paint.AddHandler paintHandler // Handler added.
let btn = new Button()
btn.Text <- "Remove Handler"
btn.Width <- 200;
btn.Click.Add (fun e ->
form.Paint.RemoveHandler paintHandler // Handler removed.
form.Invalidate() // Redraw
)
form.Controls.Add btn
form.Show()
请务必注意AddHandler
/ RemoveHandler
采用普通委托,但Add
采用不同签名的功能。 (缺少sender
参数。)