Ошибка FS3039: прямая ссылка на сгенерированный тип "MyType" не разрешена

Поставщик следующего типа должен был создать 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/info/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: прямая ссылка на сгенерированный тип "MyType" не является допускается.

Я добавил вызов конструктора , но он не помог

Провайдер типа сделан намеренно намеренно

Есть ли ошибка в моем провайдере типов?

Ответы

Ответ 1

Я не уверен, как сделать его полностью работоспособным, но я думаю, причина, по которой вы получаете ошибку, заключается в том, что параметризованный тип является стираемым типом (в то время как тип, который вы возвращаете после статических параметров, предоставляется не стертый тип).

Добавление 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

Итак, возможно, что-то еще, что я тоже не хватает. Возможно, это может указывать вам в правильном направлении!