目前已在F#中添加了对反射的支持,但它不适用于度量类型。是否可以在F#中使用反射来测量类型?
我读过this。这是2008年,但是如果你在ildasm中检查一些像bellow这样的代码,你就看不到Units of Measure
的任何内容。
// Learn more about F# at http://fsharp.net
[<Measure>] type m
[<Measure>] type cm
let CalculateVelocity(length:float<m> ,time:float<cm>) =
length / time
ildasm输出:
.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#中反映出来。这是真的吗? 看到评论:CLR中的单位实际上根本没有被看到......在文章中。
答案 0 :(得分:18)
正如其他人已经指出的那样,当您需要获取有关已编译F#类型的一些信息时,您可以使用标准.NET反射(System.Reflection
)和F#反射,它提供有关受歧视的联合,记录等的信息( Microsoft.FSharp.Reflection
)。
不幸的是,使用这两个API中的任何一个都无法访问有关度量单位的信息,因为它们仅在编译期间进行检查,并且在运行时实际上不存在(它们无法在CLR中表示)以任何方式)。这意味着你永远无法弄清楚是否例如盒装浮点值具有某种度量单位...
您可以使用F#PowerPack中的Metadata
命名空间获取有关计量单位的部分信息。例如,以下打印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的信息。
答案 1 :(得分:3)
答案 2 :(得分:1)