我想知道是否有可能从字符串生成类似于简单类型提供程序(Record或Union,没有成员,只有与字符串名称匹配的名称)的东西,
在编译时。
混合这个
http://www.readcopyupdate.com/blog/2014/09/18/faking-typeclasses-using-static-type-constraints.html
还有这个
Create Discriminated Union Case from String
或类似的记录类型的方法。
例如,我想获得什么(不一定使用相同的方法):

[<Literal>]
let myTypeName = "One"

type SingleStringTypeProvider = ... (here implementation)


type Provided = SingleStringTypeProvider<singleString>


let typeName = typeof<Provided.One>.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 ()
这是我的script.fsx文件中的代码,可能我在犯一些愚蠢的错误。
#r @".\testType\SimpleStringProvider.dll"

open SimpleStringProvider

type x = SimpleStringProvider.SingleStringTypeProvider<"test">
script.fsx文件中的错误

非通用类型'SimpleStringProvider.SingleStringTypeProvider'
不需要任何类型参数,但是这里给出了1种类型
论点

最佳答案

您可以提供嵌套类型,而这些类型可以基于static参数。在您的示例中,Provided是类型,而Provided.One可以是嵌套类型。

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

[<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()

我尚未对此进行测试,因此您可能需要进行一些调整,但是我认为它应该可以工作。

08-06 02:13