是否有可能实现IDbSet< T&gt ;?F#中的接口? [英] Is it possible to implement the IDbSet<T> interface in F#?

查看:48
本文介绍了是否有可能实现IDbSet< T&gt ;?F#中的接口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试模拟 IDbSet< T> ,而我恰巧是在F#中做到这一点.

I am attempting to make a mock implementation of IDbSet<T>, and I happen to be doing it in 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

一切都很好,除了以下行:

Everything is fine, except for this line:

member x.Create<'TD when 'TD : not struct and 'TD :> 'T>() = Unchecked.defaultof<'TD>

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

...which gives me these compiler errors:

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

error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution

警告FS0064:此结构导致代码减少比类型注释所指示的泛型.类型变量'TD已被限制为"T"类型.

warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'TD has been constrained to be type ''T'.

错误FS0663:此类型参数的使用方式使其始终为``T当'T:not struct'

error FS0663: This type parameter has been used in a way that constrains it to always be ''T when 'T : not struct'

错误FS0661:一个或多个显式类或无法对此绑定的函数类型变量进行概括,因为它们被限制为其他类型

error FS0661: One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types

此行正在尝试实施

This line is attempting to implement this method, which according to that page has the following signature in C#:

TDerivedEntity Create<TDerivedEntity>()
where TDerivedEntity : class, TEntity

还有F#中的此签名:

abstract Create : unit -> 'TDerivedEntity  when 'TDerivedEntity : not struct and 'TEntity

当我尝试使用示例F#签名时,我遇到各种语法错误,这并不奇怪,因为该签名甚至看起来都不像有效的F#.

When I try to use the example F# signature, I get a variety of syntax errors, which doesn't surprise me because that signature doesn't even look like valid F#.

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

I'm not really sure what to make of these error messages, or how to write my constraints to satisfy both the interface and the F# compiler. I'm starting to wonder if it's even possible to implement this particular Microsoft interface in this particular Microsoft programming language. Any suggestions would be welcomed.

推荐答案

方法 Create 需要2个泛型类型参数之间的子类型约束.恐怕没有办法基于F#中的另一个将子类型约束添加到泛型类型参数.始终假定它们相等,请参见

The method Create needs a subtype constraint between 2 generic type parameters. I'm afraid there is no way to add a subtype constraint to a generic type parameter based on another one in F#. They're always assumed to be equal, see the spec New constraints of the form type :> 'b are solved again as type = 'b.

请参见与此有关的答案.

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

We should request to include this feature in the next F# version.

这篇关于是否有可能实现IDbSet&lt; T&gt ;?F#中的接口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆