有没有办法通过反射确定给定的类型参数是否满足F#比较约束?
我怀疑不会,因为表达
typedefof<Set<_>>.MakeGenericType [| typeof<System.Type> |]
Run Code Online (Sandbox Code Playgroud)
似乎没有错误.不过,我想听听一些有关这方面的权威意见.
约束类型:比较在以下情况下成立:
约束'T when 'T :> IComparable可以用CIL编码并反映在其上,而两者都不是'T when 'T : comparison.
由于这两个约束不相等,因此comparable使用IComparable约束的标记类型有点误导,因为它使得无法使用反射区分两者.
equality约束与约束之间存在类似的关系IEquatable<_>.
编辑
杰克提到comparison约束可以用F#元数据编码,这促使我查看PowerPack中的元数据阅读器.它可用于检测约束:
open Microsoft.FSharp.Metadata
let setEntity = FSharpAssembly.FSharpLibrary.GetEntity("Microsoft.FSharp.Collections.FSharpSet`1")
for typeArg in setEntity.GenericParameters do
printfn "%s - comparison=%b"
typeArg.Name
(typeArg.Constraints |> Seq.exists (fun c -> c.IsComparisonConstraint))
Run Code Online (Sandbox Code Playgroud)
这是一个人为的例子,展示了实施IComparable和满足之间的差异comparison:
type A() =
interface IComparable with
member __.CompareTo(_) = 0
[<NoComparison>]
type B() =
inherit A()
type C<'T when 'T : comparison>() = class end
type D<'T when 'T :> IComparable>() = class end
let c = C<B>() //ERROR
let d = D<B>() //OK
Run Code Online (Sandbox Code Playgroud)