C# LINQ查询InjectAttribute返回0结果及多查询合并优化问题
问题根因
第二个查询返回0条结果的核心原因是:InjectAttribute是标注在类的字段上,而非标注在类本身。你调用的type.GetCustomAttributes<InjectAttribute>()只会查询当前类型(类、接口等)自身挂载的特性,不会遍历类型内部的字段/属性的特性,自然找不到任何结果。
修复方案
要收集所有用到的InjectAttribute,需要额外遍历每个类型的所有字段:
var injectors = ( from type in types from field in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic) from attr in field.GetCustomAttributes<InjectAttribute>() select attr ).ToList();
修改后就能正确拿到所有字段上标注的InjectAttribute。
查询合并优化
完全可以把3个查询合并,减少中间集合的内存占用,逻辑更紧凑。如果担心重复遍历程序集影响性能,可以先把所有被引用的注入类型缓存到HashSet,再做过滤,性能和可读性都更好:
// 先缓存所有被Inject特性引用的类型 var injectedTypes = new HashSet<Type>( from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() from field in type.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic) let attr = field.GetCustomAttribute<InjectAttribute>() where attr != null select attr.ServiceType ); // 一步完成过滤+服务注册 (from assembly in AppDomain.CurrentDomain.GetAssemblies() from type in assembly.GetTypes() let injectableAttr = type.GetCustomAttribute<InjectableAttribute>() where injectableAttr != null && injectableAttr.ProvidedIn == ProvidedIn.Root && injectedTypes.Contains(type) select type).ToList() .ForEach(service => services.Add(Activator.CreateInstance(service)));
这种实现比拆分3段独立查询的性能更高,也避免了不必要的全局中间集合。
内容的提问来源于stack exchange,提问作者Get Off My Lawn
相关产品推荐
相关产品推荐

