F#如何列出具有自定义属性的函数?

时间:2015-02-08 08:49:19

标签: f# attributes

我试图创建某种接口,但我找不到如何在F#中使用自定义属性,因为MSDN仅显示CLR属性的使用。这就是我想要实现的目标:

open System

type Command (name : string) =
    inherit Attribute()    
    member this.Name = name

[<Command("something")>]
let doSomething () = 
    Console.Write("I'm doing something") 

[<Command("somethingElse")>]
let doSomethingElse () =
    Console.Write("I'm doing something else") 

[<EntryPoint>]
let main args =
    let command = Console.ReadLine()
    // find function where Command.Name = command and call it
    Console.Read()
    0

2 个答案:

答案 0 :(得分:4)

要扩展answer,更通用的方法是获取所有类型,然后过滤具有您正在寻找的属性的函数(因为一旦您的应用程序增长,您的方法就会崩溃)不再将所有内容“打包”到Program类中:

let getCommands () =
    let types = Assembly.GetExecutingAssembly().GetTypes()
    let commands = 
        types 
        |> Array.collect (fun typ -> typ.GetMethods())
        |> Array.choose (fun mi -> 
            mi.CustomAttributes 
            |> Seq.tryFind (fun attr -> attr.AttributeType = typeof<Command>)
            |> Option.map (fun attr -> attr, mi))

    let commandsMap = 
        commands
        |> Seq.map (fun (attr, mi) -> 
            let name =
                let arg = attr.ConstructorArguments.[0]
                unbox<string> arg.Value
            name, mi)
        |> Map.ofSeq

    commandsMap

这将获取执行程序集中所有类型的所有函数,然后过滤掉所有没有命令属性的函数。然后它构建一个映射,其中键是属性参数,值是函数的MethodInfo

答案 1 :(得分:0)

好的,找到了。

Reflection.Assembly.GetExecutingAssembly().GetType("Program").GetMethods()

Program typename在代码中不可行,因此无法在typeof<Program>中使用,但此类型存在且可从汇编中获取。