简体   繁体   English

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

[英]F# how to list functions with custom attribute?

I'm trying to create some kind of interface, but i cannot find how to use custom attributes in F# as MSDN only shows usage of CLR attributes. 我正在尝试创建某种类型的界面,但是我找不到如何在F#中使用自定义属性,因为MSDN仅显示CLR属性的用法。 This is what i want to achieve: 这是我想要实现的:

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

To extend on your answer , a more generic approach would be to get all the types and then filter the functions that have the attribute you're looking for (as your approach would break down once your application grows and no longer has everything "packed" into the Program class): 为了扩展您的答案 ,一种更通用的方法是获取所有类型,然后过滤具有您要查找的属性的函数(因为一旦您的应用程序扩展并且不再打包所有内容,您的方法就会崩溃。进入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

This gets all the functions from all the types in the executing assembly, then filters out everything that doesn't have command attribute. 这将从正在执行的程序集中的所有类型中获取所有功能,然后过滤掉没有命令属性的所有内容。 Then it builds a map where the key is the attribute argument and the value is the MethodInfo of the function. 然后,它构建一个映射,其中的键是属性参数,值是函数的MethodInfo

Ok, found it. 好,找到了。

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

Program typename is not viable in code so it cannot be used in typeof<Program> , but this type exists and can be taken from assembly. Program类型名在代码中不可行,因此无法在typeof<Program> ,但是该类型存在并且可以从汇编中获取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM