重複の可能性:
特定の属性を持つすべてのクラスを検索する
アセンブリで、特定のクラス属性のすべてのインスタンスを取得したいと考えています。つまり、特定の属性を持つクラスのリストが必要です。
通常、メソッドを使用して属性をフェッチできるクラスがありますGetCustomAttributes
。
特定の属性を持つ人のリストを作成することはできますか?
重複の可能性:
特定の属性を持つすべてのクラスを検索する
アセンブリで、特定のクラス属性のすべてのインスタンスを取得したいと考えています。つまり、特定の属性を持つクラスのリストが必要です。
通常、メソッドを使用して属性をフェッチできるクラスがありますGetCustomAttributes
。
特定の属性を持つ人のリストを作成することはできますか?
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();
}
これはリフレクションを使用して行うことができます。これ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();
var list = asm.GetTypes()
.Where(t => t.GetCustomAttributes().Any(a => a is YourAttribute))
.ToList();
コード例がないので、List<Type>
またはAssembly
.
public List<Type> TypesWithAttributeDefined(Type attribute)
{
List<Type> types = assembly.GetTypes();
return types.Where(t => Attribute.IsDefined(t, attribute)).ToList();
}