参考https://stackoverflow.com/a/4964791/2323934,我尝试在.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
...
它似乎有效,因为没有智能感知错误。然而该项目引发了构建错误
错误 FS1091 事件“ClockEvent”具有非标准类型。如果这 事件是用另一种 CLI 语言声明的,您可能需要访问此 使用显式 add_ClockEvent 和 remove_ClockEvent 方法的事件 为了这次活动。如果此事件在 F# 中声明,请指定该事件的类型 事件是“IDelegateEvent<>”或“IEvent<,_>”的实例。
请注意,如果删除
[<CLIEvent>]
行,错误就会消失,但事件无法在 C# 中使用
您的活动最终变得平庸。如果仔细观察,您会发现虽然已知
ClockEvent
应该具有类型 IDelegatedEvent<'a>
(因为 customEvent
返回 IDelegatedEvent
),但不 知道 'a
是什么。
这意味着成员
ClockEvent
是 generic(具有类型参数 'a
),并且不允许泛型事件。
要修复此问题,只需添加类型注释某处,以便编译器可以推断类型。可能在这里:
member __.ClockEvent : IDelegateEvent<System.EventHandler> = clockEvent
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
或者可以在这里:
let clockEvent = customEvent (fun (_ : System.EventHandler) -> ()) (fun _ -> ())
^^^^^^^^^^^^^^^^^^^
甚至在
customEvent
的签名上:
let customEvent (add : System.EventHandler -> _) remove =
^^^^^^^^^^^^^^^^^^^
具体在哪里并不重要,编译器只需要知道你想要的类型不知何故。现在你还不说。
(显然将
System.EventHandler
替换为您想要的实际委托;我使用 EventHandler
只是举例,因为它是最基本的)