代码之家  ›  专栏  ›  技术社区  ›  Saeed Amiri

F#度量单位的反射

  •  8
  • Saeed Amiri  · 技术社区  · 14 年前

    我读过 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根本看不到单元。。。在文章中。

    3 回复  |  直到 11 年前
        1
  •  18
  •   Tomas Petricek    14 年前

    正如其他人已经指出的,当您需要获得有关编译的F#类型的一些信息时,可以使用标准的.NET反射( System.Reflection )以及F#反射,提供有关受歧视结合、记录等的信息( Microsoft.FSharp.Reflection

    不幸的是,关于 计量单位 无法使用这两个api中的任何一个进行访问,因为它们仅在编译期间被检查,并且在运行时不实际存在(它们不能以任何方式在CLR中表示)。这意味着您将永远无法找出例如盒装浮点值是否具有某种度量单位。。。

    你可以得到 一些 Metadata 来自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#libraries时可以看到单元),因此您应该能够看到有关F#libraries的公共API的信息。

        2
  •  3
  •   dalle    14 年前

    度量单位只是编译时的事情,它不存在于assembly/CLR中。

    part one :

    常数注释:它们在那里 在价值观的类型中 而且,F#编译器知道规则 单位数量。

        3
  •  1
  •   ChrisF toni    14 年前

    .NET和F#反射

    System.Reflection 提供有关F#数据类型的其他信息

    Source