Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# F如何列出具有自定义属性的函数?_F#_Attributes - Fatal编程技术网

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

F# F如何列出具有自定义属性的函数?,f#,attributes,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 somet

我试图创建某种类型的接口,但我找不到如何在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
好的,找到了

Reflection.Assembly.GetExecutingAssembly().GetType("Program").GetMethods()
程序typename在代码中不可用,因此无法在typeof中使用,但此类型存在,并且可以从程序集中获取。

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

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

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

您需要了解反射:反射和属性应该是最后的手段,只有在您真正知道自己在做什么时才应该使用。你尝试过其他方法吗?@MauricioScheffer这是不真实的,不相关的。不是真的,F有一个typeof,但你不能做typeof,因为这种类型在代码中是不可行的。我已经编辑了这个答案,以使它可以理解。我只是寻找如何在类函数中找到解包,但这肯定是有用的。