我刚开始使用 F#,一些关于强制转换的问题让我非常困惑。不幸的是,我的背景阅读试图弄清楚为什么让我更加困惑,所以我正在寻找一些可以融入一般解释的具体答案......
我有一个 ReadOnlyCollection<'T> 枚举,由这个函数产生:
let GetValues<'T when 'T :> Enum> () =
(new ReadOnlyCollection<'T>(Enum.GetValues (typeof<'T>) :?> 'T[])) :> IList<'T>
我想要用它做的是找到枚举中被其值使用的所有位(即,按位或列表中的所有值一起),并将其作为通用枚举类型“T”返回。在我看来,这样做的明显方法是:
let UsedBits<'T when 'T :> Enum> () =
GetValues<'T>()
|> Seq.fold (fun acc a -> acc ||| a) 0
...除了编译失败,出现错误“声明的类型参数'T'不能在此处使用,因为类型参数无法在编译时解析。”
我可以通过首先转换为 Int32 来完成实际工作(我真的不想这样做,因为我希望这个函数适用于所有枚举,而不管底层类型如何),即:
let UsedBits<'T when 'T :> Enum> () =
GetValues<'T>()
|> Seq.map (fun a -> Convert.ToInt32(a))
|> Seq.fold (fun acc a -> acc ||| a) 0
...但结果生成为 Int32。如果我尝试将其转换回 'T,我会再次遇到编译错误。
我不想在我的问题中过于具体,因为我不确定我应该询问哪些细节,所以 - 这种方法的缺陷在哪里?我应该怎么做?
(编辑添加:,发布@Daniel的答案
唉,这似乎是我不能很好地理解上下文以理解答案的情况之一,所以......
我想我理解你的回答中内联和不同的约束在做什么,但是作为一个 F# 新手,你介意在这些事情上稍微扩展一下,这样我就可以检查我的理解是否偏离了基础?谢谢。
)