You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 00:24:04