我对下面的代码有点困惑,为什么最后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)
Run Code Online (Sandbox Code Playgroud)
它们不完全一样吗?
编辑
我也尝试过这个
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))
Run Code Online (Sandbox Code Playgroud)
但这给了我以下错误
Error 1 This expression was expected to have type
System.EventHandler<Serialization.ErrorEventArgs>
but here has type
Delegate
Run Code Online (Sandbox Code Playgroud)
编辑2 如果我这样做,从下面的Fyodor获取线索
let serializer_setting1 = new JsonSerializerSettings(Error = System.EventHandler<Serialization.ErrorEventArgs>(err_handler1))
Run Code Online (Sandbox Code Playgroud)
它的工作原理也很有意义 - 但是我仍然不明白为什么我使用Delegate的方法不起作用.
后两个例子是F#函数,它们实际上不是普通的.NET委托.
但是,为了与.NET的其余部分进行互操作,F#编译器会将F#函数转换为兼容的委托类型,因为它可以看到这是预期的类型.
在第一个示例中,Error必须是委托,因此F#编译器可以推断它必须执行转换.
在后两个示例中,函数的类型由编译器推断,而不考虑它们的使用方式,因为F#编译器仅在从上到下的单个传递中解释代码.
当编译器到达尝试分配函数的表达式时Error,该函数已经具有不正确的类型.
有关F#中委托的更多信息,请参阅文档.