f# 类型属性访问

f# type attribute access

有没有什么方法可以通过使用 string 中表示的名称来访问类型属性。大致如下:

type B = {FirstName:string; LastName:string} 
let b = { FirstName="Bob"; LastName="Smith" }  
b.``"FirstName"``

原因是我想根据基于 xml 的地图动态访问类型。

这是你可以通过反射来完成的事情。除了通用的 .NET 反射 API,F# 还附带了一个小型反射库 Microsoft.FSharp.Reflection,它提供了一些用于构造和分解基本 F# 类型(如记录)的实用函数。

您可以使用以下方法获取所有记录字段的 PropertyInfos

FSharpType.GetRecordFields(typeof<B>)

然后你可以将一条记录分解成一个值数组,然后像这样将它们放回记录中:

let fields = FSharpValue.GetRecordFields(b)
let b' = FSharpValue.MakeRecord(typeof<B>, fields) :?> B

您可以在此基础上构建自己的持久性库,但这在很大程度上是一个已解决的问题。我认为 Json.NET 现在应该可以立即处理序列化记录,当然还有一个 xml 等效项。

F# 还以类型提供程序的形式提供了一个独特的替代方案。如果你想让你的 xml 变成 "drive" 你的类型看起来如何 - 特别是如果你正在访问通过 xml 进行通信的外部资源 - 你可能想要研究 FSharp.Data and XmlProvider。它们与您在示例中所做的非常相似 - 您将类型提供程序指向 xml 样本,它会在编译期间生成与 xml 的结构相对应的类型。因此,您可以以静态类型的方式将 xml 节点名称用作 F# 代码中的常规字段名称。

类型提供程序非常适合脚本编写和探索性编程,因为它们可以节省您声明和更新类型定义的时间。但是在构建更持久的应用程序时,您可能会发现使用显式定义的类型作为表示是可取的。