Reflection 转换为委托后,报价将丢失

Reflection 转换为委托后,报价将丢失,reflection,f#,quotations,Reflection,F#,Quotations,使用F#派生模式MethodWithReflectedDefinition,我们可以从MethodInfo获取报价对象。但是,如果我们将一个F#函数或成员方法转换为委托,我们就无法获得引用,即使该函数或方法被标记为[]。以下是一个例子: open System open System.Reflection open System.Runtime.CompilerServices open Microsoft.FSharp.Quotations open Microsoft.FSharp.Quot

使用F#派生模式
MethodWithReflectedDefinition
,我们可以从
MethodInfo
获取报价对象。但是,如果我们将一个F#函数或成员方法转换为委托,我们就无法获得引用,即使该函数或方法被标记为
[]
。以下是一个例子:

open System
open System.Reflection
open System.Runtime.CompilerServices
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open NUnit.Framework

let printQuotation (methodInfo:MethodInfo) =
    match methodInfo with
    | MethodWithReflectedDefinition expr -> printfn "%A" expr
    | _ -> printfn "Cannot get quotations."

let printQuotationFromDelegate (del:Func<int, int>) =
    printQuotation del.Method

[<ReflectedDefinition>]
let foo a = a + 1

type MyClass private () =

    [<ReflectedDefinition>]
    static member Foo(a:int) =
        a + 1

[<Test>]
let test() =
    let methodInfo = typeof<MyClass>.GetMethod("Foo", BindingFlags.Static ||| BindingFlags.Public)
    printQuotation methodInfo   // works

    // cannot get quotations
    printQuotationFromDelegate(Func<_,_> MyClass.Foo)

    // cannot get quotations
    printQuotationFromDelegate(Func<_,_> foo)
但是转换的委托不使用这些函数,而是使用生成的方法,它是原始方法的副本。但不幸的是,这些生成的函数没有这样的
ReflectedDefinition
属性,我认为引号没有连接到这些生成的方法:

IL_0021: newobj instance void QuotationInDelegate/test@33::.ctor()
IL_0026: ldftn instance int32 QuotationInDelegate/test@33::Invoke(int32)
IL_002c: newobj instance void class [mscorlib]System.Func`2<int32, int32>::.ctor(object, native int)
IL_0031: call void QuotationInDelegate::printQuotationFromDelegate(class [mscorlib]System.Func`2<int32, int32>)
那么,在将报价信息转换为委托后,我们如何保留报价信息呢

IL_0021: newobj instance void QuotationInDelegate/test@33::.ctor()
IL_0026: ldftn instance int32 QuotationInDelegate/test@33::Invoke(int32)
IL_002c: newobj instance void class [mscorlib]System.Func`2<int32, int32>::.ctor(object, native int)
IL_0031: call void QuotationInDelegate::printQuotationFromDelegate(class [mscorlib]System.Func`2<int32, int32>)
.class nested assembly auto auto sealed specialname serializable beforefieldinit test@33
    extends [mscorlib]System.Object
{
    .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = (
        01 00 06 00 00 00 00 00
    )
    // Methods
    .method public specialname rtspecialname 
        instance void .ctor () cil managed 
    {
        // Method begins at RVA 0x2158
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: ret
    } // end of method test@33::.ctor

    .method assembly hidebysig 
        instance int32 Invoke (
            int32 arg
        ) cil managed 
    {
        // Method begins at RVA 0x2160
        // Code size 8 (0x8)
        .maxstack 8

        IL_0000: nop
        IL_0001: ldarg.1
        IL_0002: call int32 QuotationInDelegate/MyClass::Foo(int32)
        IL_0007: ret
    } // end of method test@33::Invoke

} // end of class test@33