我正在使用F#接口,通过创建一个简单的数据访问类。
界面是:
type IUserAccess =
abstract member GetUsers : (dbSchema.ServiceTypes.Users -> bool) -> dbSchema.ServiceTypes.Users seq
abstract member GetAllUsers : unit -> dbSchema.ServiceTypes.Users seq
在课堂上,我用这种方式调用方法:
type UserAccess() =
let db = dbSchema.GetDataContext()
interface IUserAccess with
member this.GetUsers cond =
let query = query {
for row in db.Users do
select row }
query |> Seq.where cond
member this.GetAllUsers () =
(this:>IUserAccess).GetUsers (fun _ -> true)
我有点担心的是我调用GetAllUsers
函数的方式,特别是部分(this:>IUserAccess)
。调用在同一个接口中实现的方法的最简单方法是什么?
我能想到的一个简单选项是直接在GetUsers
类中创建UserAccess()
方法,然后从GetUsers
和GetAllUsers
的接口实现中调用它,但是意味着实现了一个新的私有方法,我想避免。还有其他选择吗?
答案 0 :(得分:8)
我认为@vcsjones的解决方案可能是最好的选择,如果你想避免直接在类中定义一个单独的方法。也就是说,声明一个单独的方法实际上并不那么难看。您可以使用let
绑定(它自动编译为私有方法)使用本地定义,我认为它使代码看起来非常好:
type UserAccess() =
let db = dbSchema.GetDataContext()
let getUsers cond =
let query = query {
for row in db.Users do
select row }
query |> Seq.where cond
interface IUserAccess with
member this.GetUsers cond = getUsers cond
member this.GetAllUsers () = getUsers (fun _ -> true)
我通常非常喜欢这种风格,因为它将所有私有实现与您定义公开公开API的定义部分分开。
答案 1 :(得分:6)
F#总是显式实现接口,因此您的选项与您所说的非常相似,但您可以通过引入let绑定来避免冗余转换:
type IUserAccess =
interface
abstract member GetUsers : (obj -> bool) -> unit
abstract member GetAllUsers : unit -> unit
end
type Foo() as self =
let userAccess = self :> IUserAccess
interface IUserAccess with
member this.GetUsers(q : (obj -> bool)) : unit =
()
member this.GetAllUsers() =
userAccess.GetUsers(fun _ -> true)
我只是简化了你的界面和对象,所以我可以快速编译一些东西。