Inheritance 从F#生成类型提供程序提供的类型继承

Inheritance 从F#生成类型提供程序提供的类型继承,inheritance,f#,type-providers,Inheritance,F#,Type Providers,我有一个基本的生成型F#type提供者 [<TypeProvider>] type MyTypeProvider(config : TypeProviderConfig) as this = inherit TypeProviderForNamespaces(config) let ns = "MyNamespace" let asm = Assembly.LoadFrom(config.RuntimeAssembly) let buildTyp

我有一个基本的生成型F#type提供者

[<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 ()
[]
键入MyTypeProvider(配置:TypeProviderConfig),如下所示:
继承TypeProviderForNamespaces(配置)
让ns=“MyNamespace”
让asm=Assembly.LoadFrom(config.RuntimeAssembly)
let buildTypes(typeName:string)(args:obj[])=
设asm=ProvidedAssembly()
让srvName=args。[0]:?>字符串
... 省略
let provided=ProvidedTypeDefinition(asm、ns、typeName、某些typeof、hideObjectMethods=true、nonNullable=true、iSeries=false)
让ctor=ProvidedConstructor([],(fun->)
提供。添加成员(ctor)
假如
设参数=
[ProvidedStaticParameter(“主机”,类型,”)]
让provider=ProvidedTypeDefinition(asm,ns,“MyProvider”,某些typeof,hideObjectMethods=true,nonNullable=true,iSeries=false)
do provider.DefineStaticParameters(参数、构建类型)
执行此操作。AddNamespace(ns,[提供程序])
[]
do()
在另一个项目中,我不想直接使用提供的类型,而是通过继承它:

type Provided = MyNamespace.MyProvider<"Host123">

type Derived() = 
    inherit Provided() //Cannot inherit a sealed type
提供的类型=MyNamespace.MyProvider
类型派生()=
继承提供的()//无法继承密封类型
但是,我得到一个错误,说提供的类型是一个密封类,因此不能从中继承


这是出于设计还是我遗漏了什么?

这是F#Type提供程序SDK中的默认行为。您可以在
ProvidedTypeDefinition
类(第1241-1252行附近)中看到用于提供类型定义的属性:

您可以通过显式地为构造函数的第五个参数传递
TypeAttributes
(您必须使用接受所有参数的构造函数)来覆盖该属性。在您的
之后拾取。。。省略了
部分,看起来像这样:

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)
让派生类属性=TypeAttributes.Public | | | TypeAttributes.Class
让我们提供=
提供的类型定义(false,
命名空间(K asm,ns),
字体名,
K(某种类型的),
派生类属性,
K无,
[], 
没有一个
没有一个
K[| |],
是的,
(对)

不幸的是,它不起作用。编译器无法识别主构造函数(因为我想fsi文件没有声明它)。另外,例如,第二个参数使用类型TypeContainer,它是用RequireQualifiedAccessAttribute声明的,因此我应该使用全名“ProviderImplementation.ProvidedTypes.TypeContainer.Namespace(K asm,ns)”,但即使是编译器也无法识别它(我认为原因与此相同)。因此,您建议的解决方案在技术上是正确的,但是如果不调整SDK源代码,就无法使用它
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)