Как вы уже упоминали, вам нужно создать экземпляр делегата:
let ch = new MouseButtonEventHandler(fun obj args ->
printfn "Click!")
Тогда вы можете использовать ch
в качестве аргумента для AddHandler
или RemoveHanlder
. Причина в том, что значение функции F # на самом деле не представлено как тип делегата. Он имеет свой собственный тип, который не является делегатом (см. Также другое обсуждение SO ). Вы можете увидеть разницу, если вы посмотрите на типы в F # интерактив (или VS IntelliSense):
> (fun (o:obj) (a:MouseButtonEventArgs) -> printfn "Click!")
val it : obj -> MouseButtonEventArgs -> unit = (...)
> new MouseButtonEventHandler(fun o a -> printfn "Click!")
val it : MouseButtonEventHandler = (...)
Что может сбивать с толку, так это то, что F # также допускает неявное преобразование значения лямбда-функции в совместимый тип делегата при вызове метода, однако это работает, только если вы предоставляете лямбда-функцию непосредственно в качестве аргумента (я думаю):
fe.MouseLeftButtonDown.AddHandler(fun obj args ->
printfn "Click!")
Другая причина, по которой вам все еще нужны делегаты в F #, заключается в том, что делегаты имеют четко определенную семантику сравнения (они сравниваются как любые другие ссылочные типы). Для функций спецификация F # не говорит, когда они равны.