【问题标题】:Creating F# record through reflection通过反射创建 F# 记录
【发布时间】:2011-11-15 15:58:10
【问题描述】:

如何使用反射在 F# 中创建记录类型?谢谢

【问题讨论】:

  • 你为什么要这样做?为什么需要专门的记录?
  • @Giuseppe:我用一个如何做到这一点的例子更新了我的答案。

标签: .net reflection f#


【解决方案1】:

您可以使用FSharpValue.MakeRecord[MSDN] 创建记录实例,但我认为 F# 中没有任何内容可用于定义记录类型。但是,记录会编译为简单的类,因此您可以像在 C# 中那样构建一个类。 TypeBuilder[MSDN] 可能是一个很好的起点。

更新

[<CompilationMapping(SourceConstructFlags.RecordType)>] 添加到类型是使其成为记录所需的全部内容。这是一个如何在运行时执行此操作的示例。

let asmName = AssemblyName("Foo")
let asm = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndCollect)
let moduleBldr = asm.DefineDynamicModule("Test")
let typeBldr = moduleBldr.DefineType("MyRecord", TypeAttributes.Public)
let attrBldr = CustomAttributeBuilder(
                typeof<CompilationMappingAttribute>.GetConstructor([|typeof<SourceConstructFlags>|]), 
                [|box SourceConstructFlags.RecordType|])
typeBldr.SetCustomAttribute(attrBldr)
let typ = typeBldr.CreateType()
printfn "%b" <| FSharpType.IsRecord(typ) //true

【讨论】:

  • 我已经构建了一个 TypeBuilder,但我想创建一个使用 Expr.NewRecord 和我构建的 System.Type 的报价;我需要特殊类型来调用 Expr.NewRecord 吗?
  • @GiuseppeMaggiore 我认为该类型可能需要使用特殊属性进行标记(并且可能还具有与 F# 编译器生成的记录完全相同的形式)。你有没有看 F# 使用 ILSpy/Reflector 生成的类型(我确定它们标有某些属性,但资源中可能也有一些东西,你自己很难做到)?
  • @Tomas:知道为什么没有FSharpType.MakeRecordType,因为有MakeTupleTypeMakeFunctionType 方法吗?
  • @Daniel 我认为这是因为创建元组或函数类型只涉及创建代表现有类型(TupleFSharpFunc)的某种组合的 System.Type,但生成记录实际上涉及发射使用反射的类型(更复杂并且有更多选项,例如将类型放入哪个程序集中......)
  • 顺便说一句:+1 实际实现它:-)
猜你喜欢
  • 2011-03-02
  • 2022-12-07
  • 1970-01-01
  • 2014-06-19
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 2017-01-24
相关资源
最近更新 更多