robkuz
robkuz

Reputation: 9914

Defining Delegate

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

Answers (1)

Mark Seemann
Mark Seemann

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

Related Questions