With reference to https://stackoverflow.com/a/4964791/2323934, I am trying to use that code in .NET 8
let customEvent add remove =
{ new IDelegateEvent<_> with
member this.AddHandler del = add del
member this.RemoveHandler del = remove del }
...
let clockEvent = customEvent (fun _ -> ()) (fun _ -> ())
[<CLIEvent>]
member __.ClockEvent = clockEvent
...
It seems to work as there are no intellisense errors. However the project raises a build error
Error FS1091 The event 'ClockEvent' has a non-standard type. If this event is declared in another CLI language, you may need to access this event using the explicit add_ClockEvent and remove_ClockEvent methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<>' or 'IEvent<,_>'.
Note that the error disappears if I remove the [<CLIEvent>]
line, but then the event cannot be consumed in C#
Your event ends up generic. If you look closely, you'll see that while it's known that ClockEvent
should have type IDelegatedEvent<'a>
(because customEvent
returns a IDelegatedEvent
), it is not known what 'a
is.
This means that member ClockEvent
is generic (has a type parameter 'a
), and generic events aren't allowed.
To fix, just add a type annotation somewhere, so that the compiler can infer the type. Could be here:
member __.ClockEvent : IDelegateEvent<System.EventHandler> = clockEvent
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Or could be here:
let clockEvent = customEvent (fun (_ : System.EventHandler) -> ()) (fun _ -> ())
^^^^^^^^^^^^^^^^^^^
Or even on customEvent
's signature:
let customEvent (add : System.EventHandler -> _) remove =
^^^^^^^^^^^^^^^^^^^
Doesn't matter where exactly, the compiler just needs to know the type you want somehow. Right now you're not telling it.
(obviously replace System.EventHandler
with the actual delegate you want there; I used EventHandler
just for example, because it's the most basic one)