Наследование от предоставляемого провайдером порождающего типа F # - PullRequest
0 голосов
/ 26 июня 2018

У меня есть этот базовый генеративный провайдер типа F #

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

    let ns = "MyNamespace"
    let asm = Assembly.LoadFrom(config.RuntimeAssembly)

    let buildTypes (typeName:string) (args:obj[]) =
        let asm = ProvidedAssembly()
        let srvName = args.[0] :?> string
        ... omitted
        let provided = ProvidedTypeDefinition(asm, ns, typeName, Some typeof<MyRuntimeType>, hideObjectMethods = true, nonNullable = true, isErased = false)
        let ctor = ProvidedConstructor([], (fun _ -> <@@ MyRuntimeType() @@>))
        provided.AddMember(ctor)
        provided
    let parameters = 
        [ ProvidedStaticParameter("Host", typeof<string>, "") ]

    let provider = ProvidedTypeDefinition(asm, ns, "MyProvider", Some typeof<obj>, hideObjectMethods = true, nonNullable = true, isErased = false)
    do provider.DefineStaticParameters(parameters, buildTypes)
    do this.AddNamespace(ns, [provider])

[<assembly:TypeProviderAssembly()>]
do ()

В другом проекте я хочу использовать предоставленный тип не напрямую, а наследуя его:

type Provided = MyNamespace.MyProvider<"Host123">

type Derived() = 
    inherit Provided() //Cannot inherit a sealed type

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

1 Ответ

0 голосов
/ 26 июня 2018

Это поведение по умолчанию в SDK поставщика типов F #.Атрибуты, используемые для определений предоставленного типа, можно увидеть в ProvidedTypes.fs в классе ProvidedTypeDefinition (вокруг строк 1241-1252):

    static let defaultAttributes isErased = 
        TypeAttributes.Public ||| 
        TypeAttributes.Class ||| 
        TypeAttributes.Sealed ||| 
        enum (if isErased then int32 TypeProviderTypeAttributes.IsErased else 0)

Вы можете переопределить это, явно передавTypeAttributes для пятого параметра конструктора (вам придется использовать конструктор, который принимает все параметры).Подняв после вашего ... omitted раздела, это будет выглядеть примерно так:

let derivableClassAttributes = TypeAttributes.Public ||| TypeAttributes.Class

let provided = 
    ProvidedTypeDefinition(false, 
                           TypeContainer.Namespace (K asm,ns), 
                           typeName, 
                           K (Some typeof<MyRuntimeType>), 
                           derivableClassAttributes, 
                           K None, 
                           [], 
                           None, 
                           None, 
                           K [||], 
                           true, 
                           true)
...