2017-02-28 45 views
3

我试图使用自定义属性来生成用户将发布到我的控制台应用程序中的命令(字符串)的列表,并执行相应的方法。我目前卡住了,我的命令列表总是空的。获取类中的所有方法的属性列表

这里是我的属性:

public class ImporterAttribute : Attribute 
{ 
    public string Command { get; set; } 
} 

这里的类:

public class DataProcessor 
{ 
    public List<ImporterAttribute> Commands { get; set; } 

    public DataProcessor() 
    { 
     //Use reflection to collect commands from attributes 
     Commands = GetCommands(typeof(DataProcessor)); 
    } 

    public static List<ImporterAttribute> GetCommands(Type t) 
    { 
     var commands = new List<ImporterAttribute>(); 

     MemberInfo[] MyMemberInfo = t.GetMethods(); 

     foreach (MemberInfo member in MyMemberInfo) 
     { 
      var att = (ImporterAttribute)Attribute.GetCustomAttribute(member, typeof(ImporterAttribute)); 

      if (att == null) continue; 

      var command = new ImporterAttribute(); 
      command.Command = att.Command; 
      commands.Add(command); 
     } 

     return commands; 
    } 

    [Importer(Command = "?")] 
    private string Help() 
    { 
     return "Available commands: " + (from c in Commands select c.Command).Aggregate((a, x) => a + " " + x); 
    } 

    [Importer(Command = "Q")] 
    private void Quit() 
    { 
     Environment.Exit(0); 
    } 
} 

然后我用switch语句来检查用户输入对命令列表和运行要求的方法。所以我的问题是:为什么我的命令列表总是空?我想我只是误解了the docs

奖金问题:有没有人有一个更好/更实际的方法,他们使用/已经用来解决这个功能?

+0

你能改写你的例子为[MCVE(只是一个控制台应用程序),以便我们可以复制/粘贴/编译/运行/重现,而不必自行重做它? –

+0

(但是,以'GetMethods'开始而没有绑定标志只会返回公共方法,并且您没有任何具有属性的公共方法...) –

回答

3

您的代码存在的问题是您的方法是私人的。 GetMethods默认只检索公共方法,所以如果您将HelpQuit方法签名更改为public,您将得到2个命令。

如果你想保持他们私人的,你可以使用BindingFlags这样的:

t.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance); 
+0

是的,它解决了它的问题。虽然我不介意在这个特定场景中让它们公开,但有没有一种方法可以与'privates'一起使用? – Halter

+1

查看我的更新回答@Halter – Pikoh

相关问题