我正在尝试创建一个继承此类型的类型提供程序:
type BaseType() =
member val Member : string = "" with get, set
但我不知道如何使用"这个"或者" base",比如说,在构造函数中。以下是我尝试做的一个例子:
[<TypeProvider>]
type BasicProvider (config : TypeProviderConfig) as this =
inherit TypeProviderForNamespaces ()
let asm, ns = Assembly.GetExecutingAssembly(), "Namespace"
let createTypes () =
let myType = ProvidedTypeDefinition (asm, ns, "ProvidedType", Some typeof<BaseType>)
let ctor =
ProvidedConstructor [
ProvidedParameter("inputString", typeof<string>) ]
do ctor.InvokeCode <-
fun parameters ->
// base.Member doesn't actually work - how can one do this?
<@@ do (base: BaseType).Member <- (%%parameters.[0]: string) @@>
do myType.AddMembers [ctor]
[myType]
do this.AddNamespace(ns, createTypes())
当我说&#34; base.Member&#34;有什么方法可以做我想做的事情。有吗
如果没有,是否有不同的推荐方法在提供的类型中存储内部状态?
答案 0 :(得分:3)
我没有对此进行过测试,但我认为以下内容可以解决这个问题:
ctor.InvokeCode <- fun parameters ->
<@@ let res = BaseType()
res.Member <- (%%parameters.[0]: string)
res @@>
传递给构造函数的InvokeCode
的表达式并不意味着新类型的构造函数的 body (如果您正在创建擦除类型提供程序) - 它只需要是任何表达式,返回您要擦除的类型的值。这意味着您可以在表达式中添加更复杂的初始化代码。
我个人更喜欢保持内联引用更简单,所以我有一个库函数:
let createBaseType (input:string) =
BaseType(Member = input)
从报价单中调用帮助程序:
ctor.InvokeCode <- fun parameters ->
<@@ createBaseType (%%parameters.[0]) @@>
然而,这只是一种风格问题 - 两种选择都应该有效。
答案 1 :(得分:2)
我在原始问题中没有意识到构造函数需要是一个函数,它创建并返回我们提供的类型的对象,而不是我们通常想到的构造函数。这使得自我引用变得更加容易:
do ctor.InvokeCode <-
fun parameters ->
<@@
let retVal = BaseType()
retVal.Member <- (%%parameters.[0]: string)
retVal @@>
请注意,对于属性和方法,参数[0]始终是对象本身(“this
”)。