Đối với hoàn trả lời Marcelo của, có bạn có thể sử dụng ngôn cho công việc này:
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
let velocity = 5
let fn (e:Expr) =
match e with
| PropertyGet (e, pi, li) -> pi.Name
| _ -> failwith "not a let-bound value"
let name = fn <@[email protected]>
printfn "%s" name
Như bạn có thể thấy trong các mã, F # let-ràng buộc giá trị định nghĩa đầu (chức năng hoặc các biến) được thực hiện như tính chất của một lớp học.
Tôi không thể tìm thấy nữa liên kết hiển thị cách một đoạn mã F # có thể được viết lại theo cách chức năng với C#. Nhìn thấy mã, nó trở nên rõ ràng lý do tại sao bạn cần một mô hình PropertyGet
.
Bây giờ, nếu bạn muốn đánh giá biểu thức, bạn sẽ cần phải cài đặt F# powerpack và tham chiếu FSharp.PowerPack.Linq
trong dự án của bạn.
Nó cho biết thêm một phương pháp EvalUntyped
trên Expr
lớp ..
open Microsoft.FSharp.Linq.QuotationEvaluation
let velocity = 5
let fn (e:Expr) =
match e with
| PropertyGet (eo, pi, li) -> pi.Name, e.EvalUntyped
| _ -> failwith "not a let-bound value"
let name, value = fn <@[email protected]>
printfn "%s %A" name value
Nếu bạn cần phải làm điều đó cho phương pháp của một ví dụ, đây là cách tôi sẽ làm điều đó:
let velocity = 5
type Foo() =
member this.Bar (x:int) (y:single) = x * x + int y
let extractCallExprBody expr =
let rec aux (l, uexpr) =
match uexpr with
| Lambda (var, body) -> aux (var::l, body)
| _ -> uexpr
aux ([], expr)
let rec fn (e:Expr) =
match e with
| PropertyGet (e, pi, li) -> pi.Name
| Call (e, mi, li) -> mi.Name
| x -> extractCallExprBody x |> fn
| _ -> failwith "not a valid pattern"
let name = fn <@[email protected]>
printfn "%s" name
let foo = new Foo()
let methodName = fn <@[email protected]>
printfn "%s" methodName
Chỉ cần để quay trở lại đoạn mã hiển thị mức sử dụng EvalUntyped
, bạn có thể thêm thông số loại rõ ràng cho Expr
và số điện thoại (:?>
) nếu bạn muốn/cần giữ mọi thứ an toàn loại:
let fn (e:Expr<´T>) = //using ´ instead of ' to avoid colorization screw-up
match e with
| PropertyGet (eo, pi, li) -> pi.Name, (e.EvalUntyped() :?> ´T)
| _ -> failwith "not a let-bound value"
let name, value = fn <@[email protected]> //value has type int here
printfn "%s %d" name value
Xin chào, cảm ơn bạn rất nhiều! Một câu hỏi bổ sung. Làm thế nào để tôi có được một giá trị trong biểu thức? –
Cảm ơn! Và một câu hỏi cuối cùng :) Nếu fn là một thành viên của một loại (thành viên this.fn = ...), làm thế nào để làm điều đó? –
Chỉ cần tò mò, tại sao bạn cần lấy tên của một giá trị/thành viên? – Stringer