F#中目前已经添加了反思支持,但是它不适用于测量类型.在F#中可以使用反射来测量类型吗?
我已经读过 this.这是2008年,但如果你检查一些代码,如在ildasm的bellow,你看不到任何关于计量单位.
我已经读过 this.这是2008年,但如果你检查一些代码,如在ildasm的bellow,你看不到任何关于计量单位.
// Learn more about F# at http://fsharp.net [<Measure>] type m [<Measure>] type cm let CalculateVelocity(length:float<m>,time:float<cm>) = length / time
输出:
.method public static float64 CalculateVelocity(float64 length,float64 time) cil managed { // Code size 5 (0x5) .maxstack 4 IL_0000: nop IL_0001: ldarg.0 IL_0002: ldarg.1 IL_0003: div IL_0004: ret } // end of method Program::CalculateVelocity
解决方法
正如其他人已经指出的那样,当您需要获取有关编译的F#类型的一些信息时,可以使用标准的.NET反射(System.Reflection)和F#反射,该反射提供有关区分的联合,记录等的信息(Microsoft.FSharp.Reflection ).
不幸的是,使用这两个API中的任何一个无法访问关于度量单位的信息,因为它们仅在编译期间被检查,并且在运行时并不存在(它们不能以任何方式在CLR中表示).这意味着你永远无法找出是否一个盒装浮点值有一定的度量单位…
您可以使用F#PowerPack中的元数据命名空间获取有关度量单位的一些信息.例如,以下打印的foo是一个单位:
namespace App open System.Reflection open Microsoft.FSharp.Metadata [<Measure>] type foo module Main = let asm = FSharpAssembly.FromAssembly(Assembly.GetExecutingAssembly()) for ent in asm.Entities do if ent.IsMeasure then printfn "%s is measure" ent.DisplayName
这读取编译器存储在编译文件中的一些二进制元数据(以便您在引用其他F#库时可以看到单位),因此您应该可以看到关于F#库的公共API的信息.