[英]Use a virtual async Task declared in C# and override it in F#
目前我有一段用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()
成員正在嘗試返回Async<unit>
但C#庫期望一個正常的空Task
。 我試過通過MSDN Control.Async
文檔,但沒有找到任何有用的。 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.