正确调用方法,该方法引用ProvideConstructor中的实例

时间:2016-05-05 04:04:12

标签: f# type-providers

如何正确地将代码提供给生成类型提供程序中的ProvidedConstructor InvokeCode,该提供程序将执行与以下相同的操作?

假设:

module Utils =
    let someFun (s : string) (inst : obj) =
          // Does something here...
          ()

我需要有效地生成类型:

type NewGeneratedType () as self =
     inherit BaseType ()

     do
         Utils.someFun "Foo" (box self)

我对基础构造函数的调用工作,但不知道如何在实例中正确切片并获得调用的函数:

let ctor = ProvidedConstructor([])
let ci = baseType.GetConstructor(BindingFlags.Public ||| BindingFlags.Instance, null, [|  |], null)
ctor.BaseConstructorCall <- fun args -> ci, args 

// I do not know how to properly call this to match the constructor above
ctor.InvokeCode <- fun args -> <@@ () @@>

3 个答案:

答案 0 :(得分:3)

它看起来像"this" argument is passed in as the last argument to the ctor

从那里你的InvokeCode函数will get run和返回的引用翻译。所以,我认为你所需要的只是:

ctor.InvokeCode <- fun args -> <@@ let me = Seq.last args @@>

答案 1 :(得分:3)

我通过以下方式解决了这个问题:

ctor.InvokeCode <- 
    fun args -> 
        let this = Seq.head args
        let boxed = Expr.Coerce(this, typeof<obj>)
        <@@  Utils.someFun "Foo" %%(boxed) @@>

请注意,尝试将前两行移动到拼接中会导致各种错误,但是当我将其拉出时,它会完美地运行。

答案 2 :(得分:1)

@ Reed Copsey,我认为你需要实际调用自己的构造函数:

假设您已经定义了NewGeneratedType已经定义的具体类型

<@@ let this = (ctor.Invoke([||])) :> NewGeneratedType
    Utils.someFun "foo" (box this)
@@>

如果未定义NewGeneratedType但本身也是提供的类型,则需要Expr.Coerce:

<@@ let this = (ctor.Invoke([||]))
    let thisTyped = %%Expr.Coerce(this, providedType)
    Utils.someFun "foo" (box this)
@@>

我不是100%肯定这个功能,但我希望这会让你受阻。