9

重複の可能性:
特定の属性を持つすべてのクラスを検索する

アセンブリで、特定のクラス属性のすべてのインスタンスを取得したいと考えています。つまり、特定の属性を持つクラスのリストが必要です。

通常、メソッドを使用して属性をフェッチできるクラスがありますGetCustomAttributes

特定の属性を持つ人のリストを作成することはできますか?

4

4 に答える 4

4
public static IEnumerable<Type> GetTypesWithMyAttribute(Assembly assembly)
{
    foreach(Type type in assembly.GetTypes())
    {
        if (Attribute.IsDefined(type, typeof(MyAttribute)))
            yield return type;
    }
}

または:

public static List<Type> GetTypesWithMyAttribute(Assembly assembly)
{
    List<Type> types = new List<Type>();

    foreach(Type type in assembly.GetTypes())
    {
        if (type.GetCustomAttributes(typeof(MyAttribute), true).Length > 0)
            types.Add(type);
    }

    return types;
}

Linq VS 私のメソッド ベンチマーク (100000 回の反復):

Round 1
My Approach:     2088ms
Linq Approach 1: 7469ms
Linq Approach 2: 2514ms

Round 2
My Approach:     2055ms
Linq Approach 1: 7082ms
Linq Approach 2: 2149ms

Round 3
My Approach:     2058ms
Linq Approach 1: 7001ms
Linq Approach 2: 2249ms

ベンチマーク コード:

[STAThread]
public static void Main()
{
    List<Type> list;

    Stopwatch watch = Stopwatch.StartNew();

    for (Int32 i = 0; i < 100000; ++i)
        list = GetTypesWithMyAttribute(Assembly.GetExecutingAssembly());

    watch.Stop();

    Console.WriteLine("ForEach: " + watch.ElapsedMilliseconds);

    watch.Restart();

    for (Int32 i = 0; i < 100000; ++i)
        list = GetTypesWithMyAttributeLinq1(Assembly.GetExecutingAssembly());

    Console.WriteLine("Linq 1: " + watch.ElapsedMilliseconds);

    watch.Restart();

    for (Int32 i = 0; i < 100000; ++i)
        list = GetTypesWithMyAttributeLinq2(Assembly.GetExecutingAssembly());

    Console.WriteLine("Linq 2: " + watch.ElapsedMilliseconds);

    Console.Read();
}

public static List<Type> GetTypesWithMyAttribute(Assembly assembly)
{
    List<Type> types = new List<Type>();

    foreach (Type type in assembly.GetTypes())
    {
        if (Attribute.IsDefined(type, typeof(MyAttribute)))
            types.Add(type);
    }

    return types;
}

public static List<Type> GetTypesWithMyAttributeLinq1(Assembly assembly)
{
    return assembly.GetTypes()
               .Where(t => t.GetCustomAttributes().Any(a => a is MyAttribute))
               .ToList();
}

public static List<Type> GetTypesWithMyAttributeLinq2(Assembly assembly)
{
    return assembly.GetTypes()
               .Where(t => Attribute.IsDefined(t, typeof(MyAttribute)))
               .ToList();
}
于 2013-01-21T14:15:54.250 に答える
2

これはリフレクションを使用して行うことができます。これList<Type>により、現在のアセンブリ内で を持つすべてのタイプのが取得されますMyAttribute

using System.Linq;
using System.Reflection;

// ...

var asmbly = Assembly.GetExecutingAssembly();
var typeList = asmbly.GetTypes().Where(
        t => t.GetCustomAttributes(typeof (MyAttribute), true).Length > 0
).ToList();
于 2013-01-21T14:17:32.983 に答える
1
var list = asm.GetTypes()
            .Where(t => t.GetCustomAttributes().Any(a => a is YourAttribute))
            .ToList();
于 2013-01-21T14:16:53.490 に答える
0

コード例がないので、List<Type>またはAssembly.

public List<Type> TypesWithAttributeDefined(Type attribute)
{
  List<Type> types = assembly.GetTypes();
  return types.Where(t => Attribute.IsDefined(t, attribute)).ToList();
}
于 2013-01-21T14:20:50.927 に答える