我对下面的代码感到有点困惑,为什么最后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))
它有效,这也很有意义 - 但我仍然不明白为什么我使用代表的方法不起作用。
答案 0 :(得分:5)
后两个示例是F#函数,它们实际上是不是正常的.NET代理。
然而,为了与.NET的其余部分进行互操作,F#编译器会在看到这是期望的类型时将F#函数转换为兼容的委托类型。
在第一个示例中,Error
必须是委托,因此F#编译器可以推断它必须执行转换。
在后两个例子中,编译器推断出函数的类型,而没有考虑它们的使用方式,因为F#编译器只能从上到下一次解释代码。
当编译器到达尝试将函数分配给Error
的表达式时,该函数的类型已经不正确。
有关F#中代理人的更多信息,请参阅the documentation。