定义代表

rob*_*kuz 2 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)
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的方法不起作用.

Mar*_*ann 5

后两个例子是F#函数,它们实际上不是普通的.NET委托.

但是,为了与.NET的其余部分进行互操作,F#编译器会将F#函数转换为兼容的委托类型,因为它可以看到这是预期的类型.

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

在后两个示例中,函数的类型由编译器推断,而不考虑它们的使用方式,因为F#编译器仅在从上到下的单个传递中解释代码.

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

有关F#中委托的更多信息,请参阅文档.

  • 你忘了提到手动转换是可能的:`Error = EventHandler <ErrorEventArgs>(err_handler1)` (3认同)