F#类型约束和反射 [英] F# type constraints and reflection

查看:87
本文介绍了F#类型约束和反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以通过反射确定给定类型参数是否满足F#比较约束?

Is there any way to determine whether a given type parameter satisfies the F# comparison constraint through reflection?

我怀疑不是,因为该表达方式

I would suspect not, since the expression

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

似乎没有错误.不过,我还是想听听一些权威意见.

appears to yield no errors. Still, I would like to hear some authoritative opinion on this.

推荐答案

引自Don Syme详尽的

Quoting from Don Syme's thorough post on equality and comparison constraints:

约束类型:比较在以下情况下成立

  • 如果类型是命名类型,则类型定义不具有 NoComparison 属性;和
  • 类型定义实现 System.IComparable ;和
  • 任何类型的比较依赖项"也满足 ty i :比较
  • if the type is a named type, then the type definition doesn't have the NoComparison attribute; and
  • the type definition implements System.IComparable; and
  • any "comparison dependencies" of the type also satisfy tyi : comparison

约束'T when 'T :> IComparable可以在CIL中进行编码并反映出来,而'T when 'T : comparison都不是真的.

The constraint 'T when 'T :> IComparable can be encoded in CIL and reflected upon, whereas neither is true of 'T when 'T : comparison.

由于这两个约束不相等,因此用IComparable约束标记comparable类型有点误导,因为这将导致无法使用反射来区分这两个类型.

Since the two constraints are not equivalent, marking comparable types with the IComparable constraint is a bit misleading since it would make it impossible to distinguish between the two using reflection.

equality约束与IEquatable<_>之间存在相似的关系.

There's a similar relationship between the equality constraint and IEquatable<_>.

编辑

Jack提到comparison约束可以在F#元数据中进行编码,这促使我着眼于PowerPack中的元数据读取器.它可以用来检测约束:

Jack's mention that the comparison constraint could be encoded in F# metadata prompted me to look at the metadata reader in PowerPack. It can be used to detect the constraint:

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之间的差异:

Here's a contrived example that shows the disparity between implementing IComparable and satisfying 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

这篇关于F#类型约束和反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆