如何为事件成员编写类型约束?

时间:2012-05-18 04:37:43

标签: wpf f# structural-typing

WPF控件有许多事件成员,它们具有相同的名称,而不共享相同的接口或基类。 F#的类型约束允许编写函数,该函数适用于具有相同成员的所有对象。 然后,如果我可以为事件成员写类型约束, 对于许多控件,我可以用相同的方式编写curried函数,以便于属性设置。

open System.Windows.Controls
let inline click handler control =
  (^T:(member Click:IEvent<_,_>)control)
    .Add handler

Button()
|> click (fun _ -> ()) // error!

MenuItem()
|> click (fun _ -> ()) // error!

type A () =
  [<CLIEvent>]
  member __.Click = Event<_>().Publish
A() |> click (fun _ -> ()) // It works! but IntelliSense shows the member as "event A.Click .."

但上面的代码不起作用.. 我想为事件成员编写类型约束是不可能的.. 因为这是一个小问题,如果我们通过语言功能解决每个小问题, 语言将变得如此复杂,没有人可以使用! (现在F#似乎功能强大且简单)

然后我想知道解决这个问题的另一种方法,如果存在的话。

1 个答案:

答案 0 :(得分:1)

我在发布这个问题后自己解决了。您可以通过调用方法add_ *和remove_ *来访问事件成员。类型约束与调用方法一起使用。谢谢!

let inline click handler control =
  let handler = RoutedEventHandler(fun _ e -> handler e)
  (^T:(member add_Click:RoutedEventHandler->unit)control,handler)

Button() |> click (fun _ -> ()) // works!
MenuItem() |> click (fun _ -> ()) // works!