web-dev-qa-db-ja.com

リフレクションを使用してカスタム属性を持つメソッドを検索します

カスタム属性があります:

public class MenuItemAttribute : Attribute
{
}

そして、いくつかのメソッドを持つクラス:

public class HelloWorld
{
    [MenuItemAttribute]
    public void Shout()
    {
    }

    [MenuItemAttribute]
    public void Cry()
    {
    }

    public void RunLikeHell()
    {
    }
}

カスタム属性で装飾されたメソッドのみを取得するにはどうすればよいですか?

これまでのところ、私はこれを持っています:

string assemblyName = fileInfo.FullName;
byte[] assemblyBytes = File.ReadAllBytes(assemblyName);
Assembly assembly = Assembly.Load(assemblyBytes);

foreach (Type type in Assembly.GetTypes())
{
     System.Attribute[] attributes = System.Attribute.GetCustomAttributes(type);

     foreach (Attribute attribute in attributes)
     {
         if (attribute is MenuItemAttribute)
         {
             //Get me the method info
             //MethodInfo[] methods = attribute.GetType().GetMethods();
         }
     }
}

ここで必要なのは、メソッド名、戻り値の型、およびそれが受け入れるパラメーターを取得することです。

46
stoic

あなたのコードは完全に間違っています。
属性を持つすべてのtypeをループしているため、タイプが見つかりません。

すべてのタイプのすべてのメソッドをループし、属性があるかどうかを確認する必要があります。

例えば:

var methods = Assembly.GetTypes()
                      .SelectMany(t => t.GetMethods())
                      .Where(m => m.GetCustomAttributes(typeof(MenuItemAttribute), false).Length > 0)
                      .ToArray();
83
SLaks
Dictionary<string, MethodInfo> methods = Assembly
    .GetTypes()
    .SelectMany(x => x.GetMethods())
    .Where(y => y.GetCustomAttributes().OfType<MethodAttribute>().Any())
    .ToDictionary(z => z.Name);
21
JordanBean
var class = new 'ClassNAME'();
var methods = class.GetType().GetMethods().Where(m=>m.GetCustomAttributes(typeof(MyAttribute), false).Length > 0)
.ToArray();

これで、クラスにこの属性「MyAttibute」を持つすべてのメソッドができました。どこでも呼び出すことができます。

public class 'ClassNAME': IDisposable
 {
     [MyAttribute]
     public string Method1(){}

     [MyAttribute]
     public string Method2(){}

     public string Method3(){}
  }
0
Unknown Artist