F# - 我可以参考"这个"或者"自我"在类型提供商?

时间:2017-11-06 20:45:07

标签: f# type-providers

我正在尝试创建一个继承此类型的类型提供程序:

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;有什么方法可以做我想做的事情。有吗

如果没有,是否有不同的推荐方法在提供的类型中存储内部状态?

2 个答案:

答案 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”)。

相关问题