以下类型提供程序旨在创建GeneratedNamespace.MyType
,它接受类型为string
的静态参数,并且只包含一个空构造函数
namespace TypeProviderTest
open Microsoft.FSharp.Core.CompilerServices
open ProviderImplementation.ProvidedTypes
open System.Reflection
open System
[<TypeProvider>]
type MyTypeProvider(config:TypeProviderConfig) as this =
inherit TypeProviderForNamespaces()
let namespaceName="GeneratedNamespace"
let assembly = Assembly.LoadFrom(config.RuntimeAssembly)
//Provides definition, based on type parameters
let instantiationFunction typeName (typeParams:obj[]) =
match typeParams with
| [|:? string as param|] ->
//Creates an empty non-erased type
let definition = ProvidedTypeDefinition(
assembly,
namespaceName,
typeName,
Some typedefof<Object>,
IsErased = false
)
//Creates an empty constructor
let emptyCtor = ProvidedConstructor (parameters = [])
//Provides a call to base constructor
//(https://stackoverflow.com/questions/22520352/)
//Doesn't seem to help
let objCtor = typedefof<Object>.GetType().GetConstructor([||])
emptyCtor.BaseConstructorCall <- (fun _ -> objCtor,[])
emptyCtor.AddXmlDoc("Empty constructor test")
definition.AddMember(emptyCtor)
definition
| _ -> failwith "That was not supported"
let staticParams = [ProvidedStaticParameter("value",typedefof<string>)]
let t = ProvidedTypeDefinition(assembly,namespaceName,"MyType",Some typedefof<Object>)
do t.DefineStaticParameters(staticParams,instantiationFunction)
do this.AddNamespace(namespaceName,[t])
[<assembly:TypeProviderAssembly>]
do ()
当我尝试像这样使用它时
open System
open GeneratedNamespace
type X = MyType<"Abacaba">
[<EntryPoint>]
let main argv =
printfn "%A %A" typedefof<X> (new X())
Console.ReadLine() |> ignore
0
行type X = MyType<"Abacaba">
产生错误
错误FS3039:直接引用生成的类型&#39; MyType&#39;不是 允许的。
我添加了base constructor call,但它没有帮助
类型提供者是故意生成的
我的类型提供程序是否有错误?
答案 0 :(得分:6)
我不确定如何让它完全正常工作,但我认为你得到错误的原因是参数化类型是一种擦除类型(而一旦静态参数返回的类型)提供的不是擦除类型)。
将IsErased = false
添加到t
会导致错误消失:
let staticParams = [ProvidedStaticParameter("value",typedefof<string>)]
let t =
ProvidedTypeDefinition
(assembly,namespaceName,"MyType",Some typedefof<Object>,IsErased = false)
do t.DefineStaticParameters(staticParams,instantiationFunction)
有了这个,可以编译代码,但尝试使用new X()
创建实例给出:
错误FS0192:内部错误:null:GetTRefType
所以,我可能还缺少其他东西。也许它可以指出你正确的方向!