c# - 什么是 F# 的标准类型事件?
问题描述
我正在尝试从 F# 订阅/取消订阅 C# 制作的(在 RabbitMQ 客户端库中):
public event AsyncEventHandler<BasicDeliverEventArgs> Received;
public delegate Task AsyncEventHandler<in TEvent>(object sender, TEvent @event) where TEvent : EventArgs;
我设法通过执行以下操作订阅了该事件:
let subscribeAsync (channel: IModel) exchange callback =
let consumer = AsyncEventingBasicConsumer(channel)
consumer.add_Received(AsyncEventHandler<BasicDeliverEventArgs>(fun sender args -> Task.CompletedTask))
// ...
话虽如此,我想知道为什么下面的代码无法编译:
let subscribeAsync (channel: IModel) exchange callback =
let consumer = AsyncEventingBasicConsumer(channel)
consumer.Received.AddHandler(AsyncEventHandler<BasicDeliverEventArgs>(fun sender args -> Task.CompletedTask))
// ...
因为我收到以下错误:
Program.fs(10, 14): [FS1091] The event 'Received' 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_Received and remove_Received methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<_>' or 'IEvent<_,_>'.
我查看了官方的 MS 文档,但看不到任何关于 F# 标准事件类型的参考。
解决方案
F# 会将 .NET 事件公开为IEvent
或类型的值IDelegateEvent
,具体取决于事件声明和委托类型的外观。这只能针对具有一些基本通用结构的事件执行 - 当 F# 无法执行此操作时,它会将事件的底层add
和remove
操作公开为您可以直接调用的方法。
我不确定什么是“标准事件类型”的规则是什么。但是,您可以从F# 编译器源代码的相关位中获得一些提示:
let TryDestStandardDelegateType (infoReader: InfoReader) m ad delTy =
let g = infoReader.g
let (SigOfFunctionForDelegate(_, compiledViewOfDelArgTys, delRetTy, _)) =
GetSigOfFunctionForDelegate infoReader delTy m ad
match compiledViewOfDelArgTys with
| senderTy :: argTys when (isObjTy g senderTy) &&
not (List.exists (isByrefTy g) argTys) -> Some(mkRefTupledTy g argTys, delRetTy)
| _ -> None
所以,我的猜测是“标准事件类型”需要:
- 至少有一个参数
- 第一个参数必须是类型
object
- 没有
byref
参数
推荐阅读
- python - pyspark map中嵌套if else的实现
- api - 获取社交网络上最常用的单词组合
- python - KeyError:'' 空字符串错误 Pyspark (Spark RDD)
- javascript - 您可以在 Angular 8 的管道中将日期从 UTC 转换为本地浏览器时间吗?
- matlab - 在共享一些变量的并行 n 函数中运行
- excel - 自引用单元格公式
- groovy - How to send an email using groovy script in Soap UI?
- vue.js - Access to a props in slots
- python - Python 加载 npz 文件包括 Scipy 对象
- android - 警告:配置“编译”已过时,已替换为“实施”和“API”