是否可以在F#中实现IDbSet <T>接口?

Joe*_*ler 9 f# entity-framework

我正在尝试进行模拟实现IDbSet<T>,而我恰巧在F#中进行.

type MockDbSet<'T when 'T : not struct>(items:seq<'T>) =
    let collection = ResizeArray(items)

    new () = MockDbSet(Seq.empty)

    interface IDbSet<'T> with
        member x.Add entity = collection.Add entity; entity
        member x.Attach entity = collection.Add entity; entity
        member x.Remove entity = collection.Remove entity |> ignore; entity
        member x.Create() = Unchecked.defaultof<'T>
        member x.Create<'TD when 'TD : not struct and 'TD :> 'T>() = Unchecked.defaultof<'TD>
        member x.Find([<ParamArray>] values) = raise <| NotImplementedException()
        member x.Local = Collections.ObjectModel.ObservableCollection(collection)

    interface System.Collections.Generic.IEnumerable<'T> with
        member x.GetEnumerator() = 
            collection.GetEnumerator() :> System.Collections.Generic.IEnumerator<_>

    interface System.Collections.IEnumerable with
        member x.GetEnumerator() =
            collection.GetEnumerator() :> System.Collections.IEnumerator

    interface IQueryable<'T> with
        member x.ElementType = typeof<'T>
        member x.Expression =
            collection.AsQueryable().Expression
        member x.Provider =
            collection.AsQueryable().Provider
Run Code Online (Sandbox Code Playgroud)

一切都很好,除了这一行:

member x.Create<'TD when 'TD : not struct and 'TD :> 'T>() = Unchecked.defaultof<'TD>
Run Code Online (Sandbox Code Playgroud)

...这给了我这些编译错误:

错误FS0698:无效约束:用于约束的类型是密封的,这意味着约束只能通过最多一个解决方案来满足

警告FS0064:此构造导致代码不像类型注释所指示的那样通用.类型变量'TD已被约束为类型''T'.

错误FS0663:此类型参数的使用方式限制它始终为'T时'T:not struct'

错误FS0661:此绑定的一个或多个显式类或函数类型变量无法一般化,因为它们被约束为其他类型

这一行试图实现这个方法,根据该页面在C#中有以下签名:

TDerivedEntity Create<TDerivedEntity>()
where TDerivedEntity : class, TEntity
Run Code Online (Sandbox Code Playgroud)

而这个签名在F#中:

abstract Create : unit -> 'TDerivedEntity  when 'TDerivedEntity : not struct and 'TEntity
Run Code Online (Sandbox Code Playgroud)

当我尝试使用示例F#签名时,我得到了各种语法错误,这并不让我感到惊讶,因为该签名甚至看起来不像有效的F#.

我不确定如何处理这些错误消息,或者如何编写我的约束来满足接口和F#编译器.我开始怀疑是否有可能在这种特定的Microsoft编程语言中实现这个特定的Microsoft接口.任何建议都会受到欢迎.

Gus*_*Gus 8

该方法Create需要2个泛型类型参数之间的子类型约束.我担心没有办法根据F#中的另一个参数向泛型类型参数添加子类型约束.它们总是被假定为相等,请参见规范 表单类型的新约束:>'b再次求解为type ='b.

查看类似问题的相关答案.

我们应该要求在下一个F#版本中包含功能.

  • 是的,在这里创建一个涵盖实际场景的新功能请求是绝对有意义的.这种情况很少见,但有些图书馆无法使用F#,这是一个巨大的痛苦,并没有解决方法. (4认同)
  • @kvb我更新了建议的链接.我们投票吧! (2认同)