如果我有一個函數,在另一個功能:從函數參數檢索屬性
[<SomeAttribute()>]
let f (g:unit->unit) =
//Want to get g's custom attributes
我如何可以訪問F G的自定義屬性?
我想我在這裏錯過了一些非常明顯的東西。
如果我有一個函數,在另一個功能:從函數參數檢索屬性
[<SomeAttribute()>]
let f (g:unit->unit) =
//Want to get g's custom attributes
我如何可以訪問F G的自定義屬性?
我想我在這裏錯過了一些非常明顯的東西。
這不是一般的可能,因爲當使用函數作爲參數(例如f foo
),F#編譯器包裝了foo
值成一些對象。從這個對象中提取實際的方法參考foo
將是非常困難的(只有在編譯器沒有做一些優化的情況下它纔會起作用)。
但是,您可以使用F#語句獲得所需的行爲。而不是採取功能unit -> unit
,您的f
可以引用函數Expr<unit -> unit>
。然後您可以使用f <@ foo @>
調用該函數,該函數可以提取方法參考,並且還可以調用foo
。
這裏是一個例子。它需要引用F#PowerPack(以便它可以評估報價)。在這個簡單的情況下,評估應該是相當有效:
#r @"FSharp.PowerPack.Linq.dll"
type SomeAttribute(name:string) =
inherit System.Attribute()
member x.Name = name
// Example function with some attribute
[<SomeAttribute("Test")>]
let g() = printfn "Hello"
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.QuotationEvaluation
// Takes a quotation instead of a function value
let f (g:Expr<unit->unit>) =
// Extract method info & attributes from the quotation
match g with
| DerivedPatterns.Lambdas(_, Patterns.Call(_, mi, _)) ->
let attrs = mi.GetCustomAttributes(typeof<SomeAttribute>, false)
for a in attrs |> Seq.cast<SomeAttribute> do
printfn "%A" a.Name
| _ ->
failwith "Argument must be of the form <@ foo @>!"
// Compile the function so that it can be executed (the compilation
// takes some time, but calling invoke should be fast)
let invoke = g.Compile()()
invoke()
invoke()
// And this is how you call the function
f <@ g @>
很酷的作品,謝謝! – 2011-05-04 20:12:29
let f (g:unit->unit) =
printfn "%d" (g.GetType().GetCustomAttributes(true).Count())
我認爲這會返回類型屬性而不是實例屬性(例如ReflectedDefinition不會出現)。 – 2011-05-04 10:03:53
是的,這並不完全。嗯.... – 2011-05-04 10:05:13
非常類似的問題:http://stackoverflow.com/questions/1575180/retrieve-methodinfo-of-af-function(你想要什麼不似乎是可能的,除非你知道裝配和功能的名稱。) – wmeyer 2011-05-04 10:13:06
啊,謝謝。我想知道是否應該關閉/刪除這個問題,因爲它顯然是重複的? – 2011-05-04 10:15:14
我認爲你可以接受Tomas的答案。我也使用相同的方法(在嘗試破解CIL後,CIL在發佈模式下不起作用)。 – Stringer 2011-05-04 14:10:14