我有一个类型:
type DictionaryCache<'a, 'b when 'a :comparison>()
我还有另一种类型,其中包含一些DictionaryCache
:
type Cache() =
let user = new DictionaryCache<int, User>()
let userByLogin = new DictionaryCache<string, User>()
member this.User = user
member this.UserByLogin = userByLogin
在最后一个类型中,我想创建一个泛型函数,它将根据输入参数返回一个成员:
member this.CacheNameToDictionary (cacheName: string) : DictionaryCache<'a, 'b> option =
match cacheName with
| "userByAutoincrementedId" -> Some(this.User)
| "userByLogin" -> Some(this.UserByLogin)
| _ -> None
但由于type mismatch
而无效。
有没有办法重写这个功能?
更新:这是我需要做的完整代码:
type Cache() =
let user = new DictionaryCache<int, User>()
let userByLogin = new DictionaryCache<string, User>()
static let mutable instance = lazy(new Cache())
static member Instance with get() = instance.Value
member this.User = user
member this.UserByLogin = userByLogin
member this.Get (useCache: string) (cacheName: string) (id: 'a) longFunction exceptionFunction : 'b option =
let nameToDictionary() : DictionaryCache<'a, 'b> option =
match cacheName with
| "userByAutoincrementedId" -> Some(this.User)
| "userByLogin" -> Some(this.UserByLogin)
| _ -> None
let foo() : 'b option =
try
longFunction()
with
| exn -> exceptionFunction exn
None
match (useCache, nameToDictionary()) with
| "true", Some(dictionary) ->
match dictionary.Get id with
| Some(result) -> Some(result)
| _ -> match foo() with
| Some(result) -> dictionary.Put id result
Some(result)
| _ -> None
| _ -> foo()
答案 0 :(得分:3)
这是不可能的 - 问题是方法的返回类型将取决于它作为输入参数获取的字符串。输入字符串仅在运行时已知,但类型需要在编译时知道。
您可以使用Choice
类型,它可以让您返回多种不同类型之一:
member this.CacheNameToDictionary (cacheName: string) =
match cacheName with
| "userByAutoincrementedId" -> Choice1Of3(this.User)
| "userByLogin" -> Choice2Of3(this.UserByLogin)
| _ -> Choice3Of3()
这样可行,但返回类型列出了所有三种选择并且非常难看:
Choice<DictionaryCache<int,User>, DictionaryCache<string,User>,unit>
此外,此方法的使用者必须对结果进行模式匹配,并以不同方式处理两个不同的词典,因此这可能不会使您的代码特别漂亮。
老实说,我认为您正在添加一个您不需要的抽象级别。如果有两个不同的密钥,那么您需要不同的代码来处理它,并且您不太可能编写可扩展的代码并添加第三种字典。