目前我有一段用 C# 编写的代码正在被一段 F# 代码使用,它们都是 .NET 库。这是问题所在:
假设我在 C# 库中有以下类:
namespace Jaxrtech.Logic
{
public class Initializer
{
public Initializer()
{
}
public async Task Setup()
{
// Run implementation independed setup here
// Now call the implementation specific override
await OnSetup();
// Do any additional setup after the implemntation specific stuff
}
// Allow for custom setup tasks to be ran by the Initializer
protected virtual async Task OnSetup()
{
// Return a completed task by default
await Task.FromResult(0);
}
}
}
然后在 F# 中被覆盖:
open System.Threading.Tasks
open Jaxrtech.Logic
type CustomInitializer() =
inherit Initializer()
...
override this.OnSetup(): Task = async {
// custom async logic here
// ex:
do! updateTables()
do! validateData()
}
(* Error: This expression was expected to have type
Task
but here has type
Async<'a>' *)
问题是 this.OnSetup()
成员(member)正在尝试返回 Async<unit>
但是 C# 库需要一个正常的空 Task
.我试过查看 MSDN Control.Async
documentation 但没有发现任何用处。 Async.StartAsTask
仍然返回一个类型化的任务,即 Task<'a>
.所以这样的事情似乎并不能解决问题:
override this.OnSetup(): Task =
let f: Async<unit> = async {
// Implementation specific setup code here
}
Async.StartAsTask f
相反,现在您会收到类似的错误消息:
This expression was expected to have type
Task
but here has type
Task<'a>'
然后您可能会问我为什么不首先使用事件。这样做的主要原因是因为您将要返回 async void
没有办法正确使用 await
在事件上完成。
最后,我幸运地控制了 C# 和 F# 库。任何合理的方式来覆盖这个 protected virtual async Task
函数或类似的将不胜感激。
最佳答案
鉴于Task<'a>
源自 Task
你可以稍微修改你的最后一个片段
override this.OnSetup(): Task =
let f: Async<unit> = async {
// Implementation specific setup code here
}
upcast Async.StartAsTask f
关于c# - 使用在 C# 中声明的虚拟异步任务并在 F# 中覆盖它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21897510/