c# - 扫描自定义属性的所有类和方法的最佳实践

标签 c# reflection performance

我第一次真正需要自己手动进行装配扫描。我遇到了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/

相关文章:

java - 使用反射读取类中定义的 protected 注释

go - 在golang中反射和类型切换后调用接口(interface)方法

java - 使用循环设置 Bean 的属性

java - VisualVM 没有反射(reflect)正确的元空间大小?

即使进行了所有优化,Android Emulator 也会延迟

c#复选框问题

C#根据其他comboBox向comboBox添加项目

java - 将注释限制在非最终字段

c# - 找不到源文件 ''

c# - 内连接后数据库表不显示数据