Моя цель - создать функцию, которая принимает обобщенную функцию c property accesser и возвращает имя свойства, к которому она обращается. Например:
type Person = { Name: string; Age: int }
let blake = { Name = "Blake"; Age = 30 }
let requestedProperty = propertyAccess (fun p -> p.Name) // should return "Name"
Я хочу, чтобы propertyAccess
было generi c и могло использоваться с любым типом. Он может иметь подпись:
'T -> 'TProperty -> string
До сих пор я пытался создать цитату из функции делегата и шаблона, соответствующего дереву выражений, в поисках PropertyGet
. К сожалению, дерево выражения цитаты имеет форму:
NewDelegate (Func`2, delegateArg0,
Application (ValueWithName (<fun:result@88>, f), delegateArg0))
, и я не могу найти PropertyGet. Как мне этого добиться?
Весь код выглядит так:
let propertyAccess (f: 'T -> 'TProperty) =
let expression = <@ f @>
let rec findProperty expr =
match expr with
| Application(ex1, ex2) -> findProperty ex1
| PropertyGet(o, info, lst) -> sprintf "Property: %s" info.Name
| Lambda(param, body) -> findProperty body
| NewDelegate(t, lst, ex) -> findProperty ex
| ValueWithName(ob, t, s) -> sprintf "ValueName: %s" s
| _ -> "Couldn't find property"
type Person = { Name: string; Age: int }
let blake = { Name = "Blake"; Age = 30 }
let requestedProperty = propertyAccess (fun p -> p.Name) // should return "Name"
Спасибо