String F#-在编译时从字符串生成简单的空类型

String F#-在编译时从字符串生成简单的空类型,string,reflection,f#,compile-time,static-typing,String,Reflection,F#,Compile Time,Static Typing,我想知道是否有可能从字符串生成类似于简单类型提供程序(记录或联合,没有成员,只有与字符串名称匹配的名称)的内容, 在编译时 混合这个 还有这个 或类似的记录类型方法 例如,我希望从中获得什么(不一定采用相同的方法): [] 让myTypeName=“一” 类型SingleStringTypeProvider=。。。(此处为实施) 提供的类型=SingleStringTypeProvider 让typeName=typeof.Name 最终结果: 一个是编译时的类型(而不是方法或函数) 编辑

我想知道是否有可能从字符串生成类似于简单类型提供程序(记录或联合,没有成员,只有与字符串名称匹配的名称)的内容, 在编译时

混合这个

还有这个

或类似的记录类型方法

例如,我希望从中获得什么(不一定采用相同的方法):

[]
让myTypeName=“一”
类型SingleStringTypeProvider=。。。(此处为实施)
提供的类型=SingleStringTypeProvider
让typeName=typeof.Name
最终结果: 一个是编译时的类型(而不是方法或函数)

编辑 正如第一个答案(非常感谢:)中所建议的那样,我已经尝试使用提供的类型来实现它,但是当我尝试从脚本文件访问类型提供程序时,我仍然很困难,显然我只看到创建的类型,而没有看到类型提供程序本身

module SimpleStringProvider

open ProviderImplementation.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices

[<TypeProvider>]
type SingleStringTypeProvider (config : TypeProviderConfig) as this =
    inherit TypeProviderForNamespaces (config)

    let asm = System.Reflection.Assembly.GetExecutingAssembly()
    let ns = "SimpleStringProvider"
    let stringProvider = ProvidedTypeDefinition(asm, ns, "SingleStringTypeProvider", Some(typeof<obj>))

    // Define one static parameter with type name
    let parameter = ProvidedStaticParameter("TypeName", typeof<string>)
    do stringProvider.DefineStaticParameters([parameter], fun typeName args ->
    // Create the main type (this corresponds to `Provided`)    
    let resTy = ProvidedTypeDefinition(asm, ns, typeName, Some(typeof<obj>))

    // Add a nested type as a member using the name from the parameter
    let typeName = args.[0] :?> string
    ProvidedTypeDefinition(typeName, None)
    |> resTy.AddMember

    resTy )


[<assembly:TypeProviderAssembly>]
do ()
模块SimpleStringProvider
打开ProviderImplementation.ProvidedTypes
打开Microsoft.FSharp.Core.CompilerServices
[]
键入SingleStringTypeProvider(配置:TypeProviderConfig),如下所示=
继承TypeProviderForNamespaces(配置)
设asm=System.Reflection.Assembly.GetExecutionGassembly()
让ns=“SimpleStringProvider”
让stringProvider=ProviderdTypeDefinition(asm,ns,“SingleStringTypeProvider”,Some(typeof))
//使用类型名称定义一个静态参数
let parameter=ProvidedStaticParameter(“TypeName”,typeof)
do stringProvider.DefineStaticParameters([parameter],有趣的typeName参数->
//创建主类型(对应于“提供的”)
让resTy=ProvidedTypeDefinition(asm、ns、typeName、Some(typeof))
//使用参数中的名称添加嵌套类型作为成员
让typeName=args。[0]:?>字符串
提供的类型定义(类型名称,无)
|>resTy.AddMember
resTy)
[]
do()
这是我的script.fsx文件中的代码,我想我可能犯了一些愚蠢的错误

#r @".\testType\SimpleStringProvider.dll"

open SimpleStringProvider

type x = SimpleStringProvider.SingleStringTypeProvider<"test">
#r@.\testType\SimpleStringProvider.dll
打开SimpleStringProvider
类型x=SimpleStringProvider.SingleStringTypeProvider
script.fsx文件中出现错误

非泛型类型“SimpleStringProvider.SingleStringTypeProvider” 不需要任何类型参数,但这里给出了1个类型参数 论据


您可以提供嵌套类型,这些类型可以基于静态参数。在您的示例中,
提供的
是一个类型,而
提供的。一个
可以是嵌套类型

为此,您可以编写如下内容:

[<TypeProvider>]
type public SingleStringTypeProvider(cfg:TypeProviderConfig) as this =
  inherit TypeProviderForNamespaces()

  // Generate namespace and the main type provider
  let asm = System.Reflection.Assembly.GetExecutingAssembly()
  let ns = "Samples"
  let stringProvider = ProvidedTypeDefinition(asm, ns, "SingleStringTypeProvider", Some(typeof<obj>))

  // Define one static parameter with type name
  let parameter = ProvidedStaticParameter("TypeName", typeof<string>)
  do stringProvider.DefineStaticParameters([parameter], fun typeName args ->
    // Create the main type (this corresponds to `Provided`)    
    let resTy = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<IniFile>)

    // Add a nested type as a member using the name from the parameter
    let typeName = args.[0] :?> string
    ProvidedTypeDefinition(typeName, None)
    |> resTy.AddMember

    resTy )

[<assembly:TypeProviderAssembly>]
do()
[]
键入公共SingleStringTypeProvider(cfg:TypeProviderConfig),如下所示=
继承TypeProviderForNamespaces()
//生成命名空间和主类型提供程序
设asm=System.Reflection.Assembly.GetExecutionGassembly()
让ns=“样本”
让stringProvider=ProviderdTypeDefinition(asm,ns,“SingleStringTypeProvider”,Some(typeof))
//使用类型名称定义一个静态参数
let parameter=ProvidedStaticParameter(“TypeName”,typeof)
do stringProvider.DefineStaticParameters([parameter],有趣的typeName参数->
//创建主类型(对应于“提供的”)
让resTy=ProvidedTypeDefinition(asm、ns、typeName、某些typeof)
//使用参数中的名称添加嵌套类型作为成员
让typeName=args。[0]:?>字符串
提供的类型定义(类型名称,无)
|>resTy.AddMember
resTy)
[]
do()

我还没有测试过这个,所以您可能需要做一些调整,但我认为它应该可以工作。

我正在努力解决这个问题,但我仍然无法从脚本文件中正确调用它。也许我遗漏了什么?@jkone27你能发布你当前的版本并详细说明错误吗?(作为一个新问题更好,因为这样更多的人会看到它。)这里:作为旁注,我不能“继承TypeProviderForNamespaces()”而只能使用一个参数“继承TypeProviderForNamespaces(config)”重载。。。这可能是个问题吗?我正在github中使用sdk中的providedTypes.fs和providedTypes.fsi
[<TypeProvider>]
type public SingleStringTypeProvider(cfg:TypeProviderConfig) as this =
  inherit TypeProviderForNamespaces()

  // Generate namespace and the main type provider
  let asm = System.Reflection.Assembly.GetExecutingAssembly()
  let ns = "Samples"
  let stringProvider = ProvidedTypeDefinition(asm, ns, "SingleStringTypeProvider", Some(typeof<obj>))

  // Define one static parameter with type name
  let parameter = ProvidedStaticParameter("TypeName", typeof<string>)
  do stringProvider.DefineStaticParameters([parameter], fun typeName args ->
    // Create the main type (this corresponds to `Provided`)    
    let resTy = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<IniFile>)

    // Add a nested type as a member using the name from the parameter
    let typeName = args.[0] :?> string
    ProvidedTypeDefinition(typeName, None)
    |> resTy.AddMember

    resTy )

[<assembly:TypeProviderAssembly>]
do()