F# 度量单位的反射 [英] Reflection for F# units of measure

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

问题描述

目前已将反射支持添加到 F# 中,但它不适用于度量类型.是否可以在 F# 中将反射用于度量类型?我读过 这个.那是 2008 年的,但是如果你在 ildasm 中检查一些类似 bellow 的代码,你就看不到任何关于度量单位的信息.

Support for reflection has been currently added into F#, but it is not working for measure types. Is it possible to use reflection in F# for measure types? I've read this. It was for 2008, but if you check some code like bellow in ildasm you cannot see anything about 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 实际上根本看不到单元......在文章中.

So there are somethings that cannot be reflected in F#. Is it true or not? see the comment : Units actually don't get seen at all by the CLR ... in the article.

推荐答案

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

As others already pointed out, when you need to get some information about compiled F# types, you can use standard .NET reflection (System.Reflection) and F# reflection which provides information about discriminated unions, records, etc. (Microsoft.FSharp.Reflection).

不幸的是,使用这两个 API 中的任何一个都无法访问有关度量单位的信息,因为它们仅在编译期间进行检查,并且在运行时实际上并不存在(它们无法在 CLR 中表示)以任何方式).这意味着您将永远无法知道是否例如装箱的浮点值具有某种度量单位...

Unfortunatelly, information about units of measure cannot be accessed using any of these two APIs, because they are checked only during the compilation and do not actually exist at runtime (they cannot be represented in the CLR in any way). This means that you'll never be able to find out whether e.g. a boxed floating point value has some unit of measure...

您可以使用来自 F# PowerPack 的 Metadata 命名空间获取有关度量单位的一些信息.例如,以下打印出 foo 是一个单位:

You can get some information about units of measure using Metadata namespace from F# PowerPack. For example, the following prints that foo is a unit:

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 的信息.

This reads some binary metadata that the compiler stores in compiled files (so that you can see units when you reference other F# libraries), so you should be able to see informaiton about public API of F# libraries.

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

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