我第一次真正需要自己手动进行装配扫描。我遇到了C# - how enumerate all classes with custom class attribute?这让我有了
var typesWithMyAttribute =
(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
let attributes = type.GetCustomAttributes(typeof(SomeAttribute), true)
where attributes != null && attributes.Length > 0
select new { Type = type, Attributes = attributes.Cast<SomeAttribute>() })
.ToList();
这很简单,可以扩展到方法级别
var methodsWithAttributes =
(from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from method in type.GetMethods()
let attributes = method.GetCustomAttributes(typeof(SomeAttribute), true)
where attributes != null && attributes.Length > 0
select new { Type = type, Method = method,
Attributes = attributes.Cast<SomeAttribute>() })
.ToList();
我应该尝试将这 2 个结合起来以在单次扫描中执行此操作,还是只是陷入早期优化? (扫描只会在应用程序启动时执行)
由于程序集中的方法远多于类型,是否有一些不同的方法更适合扫描方法?
最佳答案
反射很慢...
我认为您已经掌握了基础知识。我建议您稍微更改代码以避免进行额外的全面扫描。
如果您必须多次执行此操作,我还建议您考虑在适当的时间段内缓存结果。
类似这样的伪代码:
... (optional caches) ...
IDictionary<Type, IEnumerable<Attributes>> typeAttributeCache = new ...
IDictionary<MethodInfo, IEnumerable<Attributes>> methodAttributeCache = new ...
... (in another method or class) ...
foreach assembly in GetAssemblies()
foreach type in assembly.GetTypes()
typeAttributes = typeAttributeCache.TryGet(...) // you know the correct syntax, trying to be brief
if (typeAttributes is null)
typeAttributes = type.GetCustomAttributes().OfType<TypeImLookingFor>();
typeAttributeCache[type] = typeAttributes;
foreach methodInfo in type.GetMethods()
methodAttributes = methodAttributeCache.TryGet(...) // same as above
if (methodAttributes is null)
methodAttributes = methodInfo.GetCustomAttributes().OfType<TypeImLookingFor>();
methodAttributeCache[type] = methodAttributes;
// do what you need to do
关于c# - 扫描自定义属性的所有类和方法的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5266790/