C# 特性全解(Conditional条件特性 + Obsolete过时特性 + 自定义特性+反射读取)
一、特性概述特性Attribute是编译期/运行期标注类、方法、字段、属性的标记用于给代码附加额外描述信息、控制编译行为本身不执行逻辑需配合编译规则或反射读取使用。分类系统内置特性、自定义特性二、Conditional 条件编译特性1. 核心作用[Conditional(编译符号)]根据编译符号是否定义决定方法是否被编译进程序集。ConditionalAttribute 和 Conditional 完全等价可简写。2. 执行规则重点如果指定编译符号已定义方法正常编译、可正常调用执行如果指定编译符号未定义方法不会编译、调用代码直接被忽略无报错、无执行常用场景调试日志、测试方法发布Release版本自动失效。3. 完整源码案例#define Debug // 定义编译符号注释则方法失效 using System; using System.Diagnostics; namespace _04ConditionalAttribute条件特性 { internal class Program { static void Main(string[] args) { T1(); // 根据Debug符号决定是否执行 } // 条件特性仅Debug符号存在时该方法才会编译生效 [Conditional(Debug)] public static void T1() { Console.WriteLine(1111); } } }4. 与 #if 预处理指令区别预处理指令屏蔽代码片段Conditional特性精准屏蔽整个方法代码更优雅、专注方法级控制三、Obsolete 过时废弃特性1. 语法格式[Obsolete(提示信息, 是否报错)]参数1自定义废弃提示文案参数2bool类型false警告提示程序可正常编译运行true编译报错禁止程序编译2. 实战源码using System; namespace _05Obsolete过时特性 { internal class Program { static void Main(string[] args) { Test1(); // 弹出编译警告 Test2(); } // 标记方法过时仅警告不报错 [Obsolete(提示Test1有可能以后会被丢弃会被test2方法进行替代, false)] static void Test1() { Console.WriteLine(Test1); } static void Test2() { Console.WriteLine(Test2); } } }3. 适用场景版本迭代、方法重构标记旧方法废弃引导开发者使用新方法。四、自定义特性核心重点1. 自定义特性固定步骤创建类继承 Attribute 基类类名建议以 Attribute 结尾添加AttributeUsage特性限制特性使用规则定义属性、构造函数用于传参存储自定义信息将自定义特性标记在 类/方法/字段/属性 上方通过反射读取特性存储的信息2. AttributeUsage 配置详解[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple true,Inherited false)]AttributeTargets指定特性可标记的位置Class标记类Method标记方法Field标记字段Property标记属性AllowMultiple true允许同一个位置多次叠加使用该特性Inherited false子类不继承父类的该特性3. 自定义特性完整定义using System; namespace _6自定义特性 { // 限制可标记类、方法允许多次使用不被继承 [AttributeUsage(AttributeTargets.Class|AttributeTargets.Method,AllowMultiple true,Inherited false)] internal class MyAttribute:Attribute { // 自定义存储字段 public string Version { get; set; } public string Name { get; set; } public string Message { get; set; } public string CallTime { get; set; } // 构造函数传参赋值 public MyAttribute(string version, string name, string message, string callTime) { Version version; Name name; Message message; CallTime callTime; } } }五、反射读取自定义特性核心实操1. 完整调用反射读取源码using System; using System.Reflection; namespace _6自定义特性 { // 类上标记自定义特性 [MyAttribute(1.0, Jack, 入口类, 2026-7-1)] internal class Program { static void Main(string[] args) { // 1. 获取目标类的Type类型 Type t1 typeof(Program); // 2. 获取目标方法的反射信息 MethodInfo info t1.GetMethod(Test1); if (info ! null) { // 执行方法 info.Invoke(null, null); // 3. 获取方法上所有自定义特性 // 参数2:false 不向父类、派生类搜索特性 object[] attrs info.GetCustomAttributes(typeof(MyAttribute), false); // 4. 遍历读取特性存储的自定义信息 foreach (MyAttribute attr in attrs) { Console.WriteLine($作者{attr.Name}描述{attr.Message}版本{attr.Version}时间{attr.CallTime}); } } } // 方法上叠加多个自定义特性AllowMultipletrue 生效 [MyAttribute(1.0, Jack, Test1方法, 2026-7-1)] [MyAttribute(2.0, Rose, Test1方法, 2026-7-2)] public static void Test1() { Console.WriteLine(Test1); } public static void Test2() { } } }2. 反射读取四步固定流程必背获取类型Type type typeof(目标类);获取成员MethodInfo / PropertyInfo / FieldInfo获取特性数组GetCustomAttributes()遍历取值强转自定义特性读取属性六、核心知识点总结特性作用关键参数Conditional根据编译符号控制方法是否编译编译符号名称Obsolete标记方法过时警告/报错提示文案、是否强制报错自定义特性自定义附加信息反射读取AttributeUsage 控制使用规则七、高频易错点Conditional 只能作用于方法不能控制普通代码行Obsolete 第二个参数 true 会直接编译报错阻断程序运行自定义特性必须继承 Attribute否则不生效AllowMultiple 默认为 false不开启则无法叠加多个特性反射读取特性时必须强转为自定义特性类型才能读取自定义属性八、背诵口诀Conditional控编译符号存在方法显Obsolete标废弃真假控制警与错自定义特性继承AttributeUsage定规多与传反射四步取信息附加数据随心览。

相关新闻