定义代表

时间:2015-10-27 14:16:36

标签: f# delegates

我对下面的代码感到有点困惑,为什么最后2次尝试定义处理程序(Delegate)不起作用。

//this works
let serializer_setting = new JsonSerializerSettings(Error = fun (sender:obj) (args:Serialization.ErrorEventArgs) -> ())

//this doesnt
let err_handler1 (sender:obj) (args:Serialization.ErrorEventArgs) = ()
let serializer_setting1 = new JsonSerializerSettings(Error = err_handler1)

//neither this
let err_handler2 = fun (sender:obj) (args:Serialization.ErrorEventArgs) -> ()
let serializer_setting2 = new JsonSerializerSettings(Error = err_handler2)

Aren他们完全一样吗?

修改

我也试过这个

 type Delegate = delegate of obj * ErrorEventArgs -> Unit
 let err_handler1 (sender:obj) (args:Serialization.ErrorEventArgs) = ()
 let serializer_setting1 = new JsonSerializerSettings(Error = new Delegate(err_handler1))

但是这给了我以下错误

Error   1   This expression was expected to have type
System.EventHandler<Serialization.ErrorEventArgs>    
but here has type
Delegate

编辑2 如果我这样做,从下面的Fyodor获取线索

let serializer_setting1 = new JsonSerializerSettings(Error = System.EventHandler<Serialization.ErrorEventArgs>(err_handler1))

它有效,这也很有意义 - 但我仍然不明白为什么我使用代表的方法不起作用。

1 个答案:

答案 0 :(得分:5)

后两个示例是F#函数,它们实际上是不是正常的.NET代理。

然而,为了与.NET的其余部分进行互操作,F#编译器会在看到这是期望的类型时将F#函数转换为兼容的委托类型。

在第一个示例中,Error必须是委托,因此F#编译器可以推断它必须执行转换。

在后两个例子中,编译器推断出函数的类型,而没有考虑它们的使用方式,因为F#编译器只能从上到下一次解释代码。

当编译器到达尝试将函数分配给Error的表达式时,该函数的类型已经不正确。

有关F#中代理人的更多信息,请参阅the documentation