特定の型パラメーターがリフレクションによってF#比較制約を満たしているかどうかを判断する方法はありますか?
表現が
typedefof<Set<_>>.MakeGenericType [| typeof<System.Type> |]
エラーは発生しないようです。それでも、私はこれについていくつかの権威ある意見を聞きたいと思います。
特定の型パラメーターがリフレクションによってF#比較制約を満たしているかどうかを判断する方法はありますか?
表現が
typedefof<Set<_>>.MakeGenericType [| typeof<System.Type> |]
エラーは発生しないようです。それでも、私はこれについていくつかの権威ある意見を聞きたいと思います。
Don Syme の等価性と比較制約に関する完全な投稿からの引用:
制約タイプ : 比較は、次の場合に保持されます。
制約'T when 'T :> IComparable
は CIL でエンコードして反映できますが、 にはどちらも当てはまりません'T when 'T : comparison
。
2 つの制約は同等ではないため、リフレクションを使用して 2 つを区別することが不可能になるためcomparable
、制約で型をマークすることは少し誤解を招きます。IComparable
equality
制約との間には同様の関係がありますIEquatable<_>
。
編集
制約を F# メタデータにエンコードできるという Jack の言及により、comparison
私は 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))
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