F# 事件,具有公开的添加/删除函数和 C# 的消耗品

问题描述 投票:0回答:1

参考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# 中使用

如何修复这个错误?

events f# .net-8.0
1个回答
0
投票

您的活动最终变得平庸。如果仔细观察,您会发现虽然已知

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
只是举例,因为它是最基本的)

© www.soinside.com 2019 - 2024. All rights reserved.