使用Reflection+Linq获取程序集中带自定义特性的属性
优化获取带自定义特性属性的实现,避免重复校验
看来你现在卡在了扫描程序集、提取带MyCustomAttribute的属性时存在重复校验的冗余问题上对吧?我来给你梳理个更高效的实现思路,一次性搞定类型筛选和属性提取,把重复的校验步骤砍掉。
首先我们先明确核心优化方向:把重复做的校验(比如类型是否继承自XX、属性是否带目标特性)合并到单次逻辑里,避免遍历过程中反复做相同检查。
优化后的完整代码示例
using System; using System.Linq; using System.Reflection; // 先补全基础定义(方便示例完整性) [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] public class MyCustomAttribute : Attribute { public string Value { get; set; } } public abstract class XX { } public class Y1 : XX { [MyCustomAttribute(Value = "val A")] public int Something {get; set;} } public class Y2 : XX { [MyCustomAttribute(Value = "val A")] public int Another {get; set;} } public class Y3 : XX { [MyCustomAttribute(Value = "val B")] public int A1 {get; set;} [MyCustomAttribute(Value = "val C")] public int A2 {get; set;} } public class AttributeProcessor { public static void ExtractTargetProperties() { // 第一步:一次性筛选出所有符合要求的类型(非抽象、继承自XX),只做一次类型校验 var validTypes = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => !t.IsAbstract && typeof(XX).IsAssignableFrom(t)); // 第二步:遍历有效类型,提取带目标特性的属性,每个属性只做一次特性检查 var targetProperties = validTypes .SelectMany(type => type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(prop => prop.GetCustomAttribute<MyCustomAttribute>() != null) .Select(prop => new { DeclaringType = type.Name, PropertyName = prop.Name, AttributeValue = prop.GetCustomAttribute<MyCustomAttribute>().Value })); // 示例输出结果 foreach (var propInfo in targetProperties) { Console.WriteLine($"类型: {propInfo.DeclaringType}, 属性: {propInfo.PropertyName}, 特性值: {propInfo.AttributeValue}"); } } }
关键优化点说明
- 砍掉重复的类型校验:我们在最开始就把所有不符合要求的类型(抽象类、不继承
XX的)过滤掉,后续遍历属性时不需要再反复检查所属类型是否合规。 - 减少特性重复获取:如果你之前的代码是先判断特性存在,然后又重新调用一次获取方法,这里直接把属性和对应特性绑定,只调用
GetCustomAttribute一次,同时完成判断和取值。 - 用LINQ链式调用简化逻辑:把筛选、提取逻辑串起来,既清晰又避免了中间变量带来的冗余,而且Linq的延迟执行特性不会额外消耗性能。
如果你的程序集不是当前执行的程序集,把Assembly.GetExecutingAssembly()替换成你需要扫描的程序集即可,比如Assembly.Load("YourTargetAssemblyName")。
内容的提问来源于stack exchange,提问作者P. Waksman
相关产品推荐
相关产品推荐

