Reputation: 9914
I am a bit confused about the code below and why the last 2 attempts to define a handler (Delegate) wont work.
//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't they exactly the same?
Edit
I also tried this
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))
But this gives me the following error
Error 1 This expression was expected to have type
System.EventHandler<Serialization.ErrorEventArgs>
but here has type
Delegate
Edit 2 Taking the clue from Fyodor below if I do this
let serializer_setting1 = new JsonSerializerSettings(Error = System.EventHandler<Serialization.ErrorEventArgs>(err_handler1))
It works and this also makes sense - However I still don't understand why my approach using a Delegate wont work.
Upvotes: 2
Views: 140
Reputation: 233150
The two latter examples are F# functions, which are actually not normal .NET delegates.
For purposes of interoperability with the rest of .NET, however, the F# compiler will convert an F# function to a compatible delegate type when it can see that this is the expected type.
In the first example, Error
must be a delegate, so the F# compiler can infer that it must perform the conversion.
In the two latter examples, the types of the functions are inferred by the compiler without taking into account how they're used, because the F# compiler only interprets code in a single pass from top to bottom.
When the compiler reaches the expression where the function is attempted assigned to Error
, the function already has the incorrect type.
See the documentation for more information about delegates in F#.
Upvotes: 5