我刚刚开始使用F#而且我的大脑已经破碎,试图弄清楚如何使用它的类型而不必采用OO类型的编程。
这是我的情况我基本上想要创建一个方法,我提供类型和Id,它返回给我数据库中的对象。
所以基本上这就是我到目前为止所做的。
let client = MongoClient()
let database = client.GetDatabase("testdb")
let lowerCase (str : string) =
str.ToLower()
let nameOf (classType: Type) =
classType.Name
let nameTypeOf<'a> =
nameOf typeof<'a>
let getCollection<'a> =
let collectionName = nameTypeOf<'a> |> lowerCase
database.GetCollection<'a> collectionName
let dbSelect<'a> id =
let collection = getCollection<'a>
collection.Find(fun(x) -> x.Id = id).First()
所以我的问题是使用dbSelect,显然它不能编译,因为x是通用的,基本上我想创建一个带有Id的接口,所有我的对象都与它接口。 我知道如何使用类和继承来实现它,但我避免在cop库之外使用实例化的类。如果有的话,最好的功能方法是什么。
这是我期待用
来称呼它type IDbObject =
abstract Id: string
type Item =
{
Id: string
Name: string
}
interface IDbObject with
member x.Id = x.Id
let item =
selectDb<Item> "5993592a35ce962b80da1e22"
任何帮助将不胜感激。 如果有人想指出我的代码有多糟糕,那么任何反馈都非常感激
答案 0 :(得分:5)
我不认为这里的解决方案与您在C#中的解决方案有很大不同。您可以约束泛型类型以使用接口成员,获得大致类似的内容:
let getCollection<'a when 'a :> IDbObject> () =
let collectionName = nameTypeOf<'a> |> lowerCase
database.GetCollection<'a> collectionName
let dbSelect<'a when 'a :> IDbObject> id =
let collection = getCollection<'a>()
collection.Find(fun (x : 'a) -> x.Id = id).First()
dbSelect
的类型应推断为string -> #IDbObject
,并在呼叫站点强制为string -> 'a
。