[<ReflectedDefinition>]
module Foo =
let x = 5
let y () = 6
let z a = a
Run Code Online (Sandbox Code Playgroud)
我试图找出如何在这种情况下获得AST的方法几次,并且一直失败。是时候在这里问问题了。
到目前为止,我认为模块将被映射到内部具有静态成员的类,因此,它应等效于:
[<ReflectedDefinition>]
type Foo =
static member x = 5
static member y () = 6
static member z a = a
let bar_members =
typeof<Bar>.GetMethods()
|> Array.filter (fun mi -> match mi with | MethodWithReflectedDefinition x -> true | _ -> false)
|> Array.map (fun m -> sprintf "%s: %A" (m.Name) (Expr.TryGetReflectedDefinition(m :> MethodBase) ) )
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,我可以使用typeof<Foo>.GetMembers()
(或GetMethods()
?!),将其强制转换为,Reflection.MethodBase
并用作的参数Expr.TryGetReflectedDefinition()
。
但不幸的是,这不适用于模块版本。
那么,该怎么做呢?
如果要使用代码,则可能要打开一些名称空间:
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.DerivedPatterns
open Microsoft.FSharp.Reflection
open System.Reflection
Run Code Online (Sandbox Code Playgroud)
问题归结为实际获取模块的类型。为此,Phillip Trelford 提供了一个很好的答案: https: //stackoverflow.com/a/14706890/5438433
基本上,您向模块添加一个辅助值,该值返回该模块的类型:
[<ReflectedDefinition>]
module Foo =
type internal IMarker = interface end
let fooType = typeof<IMarker>.DeclaringType
let x = 5
let y () = 6
let z a = a
Run Code Online (Sandbox Code Playgroud)
然后您可以使用fooType
来检索反映的定义。
let foo_members =
Foo.fooType.GetMethods()
|> Array.filter (fun mi -> match mi with | MethodWithReflectedDefinition x -> true | _ -> false)
|> Array.map (fun m -> sprintf "%s: %A" (m.Name) (Expr.TryGetReflectedDefinition(m :> MethodBase) ) )
Run Code Online (Sandbox Code Playgroud)
然后我可以打印结果:
[|"get_fooType: Some PropertyGet (Some (Call (None, TypeOf, [])), DeclaringType, [])"; “get_x:一些值(5)”;"y: 一些 Lambda (unitVar0, Value (6))"; “z:一些 Lambda (a, a)”|]
归档时间: |
|
查看次数: |
268 次 |
最近记录: |