6

特定の型パラメーターがリフレクションによってF#比較制約を満たしているかどうかを判断する方法はありますか?

表現が

typedefof<Set<_>>.MakeGenericType [| typeof<System.Type> |]

エラーは発生しないようです。それでも、私はこれについていくつかの権威ある意見を聞きたいと思います。

4

1 に答える 1

8

Don Syme の等価性と比較制約に関する完全な投稿からの引用:

制約タイプ : 比較は、次の場合に保持されます。

  • 型が名前付き型の場合、型定義にはNoComparison属性がありません。と
  • 型定義はSystem.IComparableを実装します。と
  • 型の「比較依存関係」もty iを満たします: 比較

制約'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
于 2013-01-15T15:11:22.987 に答える