如何在F#中实现返回Task(非泛型)的方法的接口

aba*_*hev 2 c# f# task-parallel-library c#-to-f# async-await

说我有接口:

interface IProductRepository
{
    Task SaveProduct(Product p);
}
Run Code Online (Sandbox Code Playgroud)

以前由C#类实现:

class CSharpProductRepository : IProductRepository
{
    public Task SaveProduct(Product p)
    {
        _db.Products.Add(p);
        return _db.SaveChangesAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想在F#中实现相同的功能:

type FSharpProductRepository =
    interface IProductRepository with
        member this.SaveProduct(p : Product) : Task = this.SaveProduct(p) // error 1

    member this.SaveProduct(p : Product) = async {
        db.Products.Add(p)
        return db.SaveChangesAsync() |> Async.AwaitTask // error 2
    }
Run Code Online (Sandbox Code Playgroud)

但是得到一个错误(1):

该表达式应该具有类型Task,但这里的类型为Async <'a>

(2):

类型约束不匹配.类型Task与类型Task <'a>不兼容

des*_*sco 5

鉴于这Task<'a>是一个子类型,Task你可以像这样做:

open System.Threading.Tasks

// stubs since I don't know what the actual code looks like
type Product = class end

type IProductRepository = 
    abstract SaveProduct: product: Product -> Task

type Db = 
    abstract Products: System.Collections.Generic.ICollection<Product>
    abstract SaveProductAsync: product: Product -> Task<int>

type Repository(db: Db) = 
    interface IProductRepository with
        member this.SaveProduct(p: Product) = 
            db.Products.Add(p)
            upcast db.SaveProductAsync(p)
Run Code Online (Sandbox Code Playgroud)