我需要在引用表达式中访问.NET字典.以下是简化版本:
let mutable dict:Dictionary<string, float> = Dictionary()
dict.Add("first", 1.0)
dict.Add("second", 2.0)
let qe2 = <@ dict.["second"] @>
Run Code Online (Sandbox Code Playgroud)
qe2的输出如下:
val qe2 : Quotations.Expr<float> =
PropertyGet (Some (PropertyGet (None, dict, [])), Item, [Value ("second")])
Run Code Online (Sandbox Code Playgroud)
当我可以直接用上面引用的代码直接创建引用表达式时,一切都很好.如何通过qe2编程方式构建同样的东西?
我知道我需要以Quotations.Expr.PropertyGet嵌套的方式以某种方式使用两次,但我不知道如何获得必要的PropertyInfo and MethodInfo对象来做这件事.
关键是要知道let dict声明被编译为静态模块类的属性.
这是一个工作样本.
module QuotationsTest
open Microsoft.FSharp.Quotations
open System
open System.Collections.Generic
open System.Reflection
let mutable dict:Dictionary<string, float> = Dictionary()
dict.Add("first", 1.0)
dict.Add("second", 2.0)
let qe2 = <@ dict.["second"] @>
let moduleType = Type.GetType("QuotationsTest")
let dictProp = moduleType.GetProperty("dict", BindingFlags.Static ||| BindingFlags.Public)
let indxProp = dict.GetType().GetProperty("Item", [| typeof<string> |])
let qe1 = Expr.PropertyGet(Expr.PropertyGet(dictProp, []), indxProp, [ Expr.Value("first") ])
printfn "%A" qe1
printfn "%A" qe2
Run Code Online (Sandbox Code Playgroud)
编译并运行以上结果如下:
> fsc QuotationsTest.fs
Microsoft (R) F# Compiler version 12.0.30815.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
> QuotationsTest.exe
PropertyGet (Some (PropertyGet (None, dict, [])), Item, [Value ("first")])
PropertyGet (Some (PropertyGet (None, dict, [])), Item, [Value ("second")])
Run Code Online (Sandbox Code Playgroud)