0

0

C# 自定义特性方法 C#如何创建和使用Attribute

月夜之吻

月夜之吻

发布时间:2026-01-22 12:11:02

|

283人浏览过

|

来源于php中文网

原创

自定义Attribute需继承System.Attribute并用AttributeUsage限定目标(如仅方法),类名建议以Attribute结尾;应用时通过反射读取,缺失时返回null而非异常,性能敏感场景应缓存或配合Source Generator在编译期处理。

c# 自定义特性方法 c#如何创建和使用attribute

怎么定义一个可作用于方法的自定义 Attribute

自定义 Attribute 必须继承 System.Attribute,且推荐显式指定 AttributeUsage 来限定它能修饰的目标(比如只允许用在方法上)。不加这个约束,编译器不会报错,但运行时反射读取时可能拿到意外位置的实例。

常见错误是忘记加 [AttributeUsage(AttributeTargets.Method)],结果特性被误标在类或属性上,后续通过 GetCustomAttribute(method) 查不到——因为根本没允许它出现在方法上。

  • 类名建议以 Attribute 结尾(如 LogExecutionTimeAttribute),C# 允许使用时省略后缀([LogExecutionTime]
  • 构造函数参数决定「位置参数」,public 属性决定「命名参数」
  • 如果需要在 JIT 或 AOT 编译阶段生效(比如影响 IL 生成),普通 Attribute 不行,得用源生成器或 ModuleInitializer 配合

如何在方法上应用并读取自定义 Attribute

应用很简单:[MyCustomAttr("value", Level = 2)];读取必须靠反射,且注意:只有在目标成员被反射访问时,.NET 才会解析并实例化该特性——不是声明时就创建对象。

典型场景是 AOP 式日志、权限校验、序列化控制。但别在热路径里反复调用 GetCustomAttribute,它有反射开销;建议启动时缓存(比如用 ConcurrentDictionary)。

  • typeof(MyClass).GetMethod("MyMethod").GetCustomAttribute() 获取单个实例
  • GetCustomAttributes(true) 的第二个参数为 true 表示查找继承链上的特性
  • 若特性类含复杂初始化逻辑(如打开文件、连接数据库),要格外小心——它会在每次反射获取时执行

为什么 GetCustomAttribute 返回 null 而不是抛异常

GetCustomAttribute() 设计为“查无此特则返回 null”,这是有意为之:绝大多数使用场景下,缺失特性是合法状态(比如某个方法不需要日志,就不打标签),没必要用异常干扰流程。

千博购物系统.Net
千博购物系统.Net

千博购物系统.Net能够适合不同类型商品,为您提供了一个完整的在线开店解决方案。千博购物系统.Net除了拥有一般网上商店系统所具有的所有功能,还拥有着其它网店系统没有的许多超强功能。千博购物系统.Net适合中小企业和个人快速构建个性化的网上商店。强劲、安全、稳定、易用、免费是它的主要特性。系统由C#及Access/MS SQL开发,是B/S(浏览器/服务器)结构Asp.Net程序。多种独创的技术使

下载

容易踩的坑是直接对返回值调用方法而不判空,导致 NullReferenceException。更隐蔽的问题是:你写了 [MyAttr],但忘了在类/方法上加 public 访问修饰符,导致反射拿不到该成员——此时 GetMethod 返回 null,再调 GetCustomAttribute 就是空引用。

  • 检查目标方法是否为 public,非 public 成员需用 BindingFlags.NonPublic | BindingFlags.Instance
  • 确认程序集已加载,且特性类型未被 Trim(发布时若启用 TrimMode=link,需在 .csproj 中添加 false
  • 调试时可用 typeof(MyClass).GetMethods().Select(m => (m.Name, m.GetCustomAttribute())) 快速验证是否被正确识别

Attribute 和 Source Generator 怎么配合避免运行时反射

Attribute 只能在运行时通过反射读取,而 Source Generator 能在编译期扫描这些特性,生成额外代码(比如自动注册 Handler、注入拦截逻辑)。这对性能敏感或 AOT 场景很关键。

比如你写了个 [Route("/api/users")],不用等请求进来再反射找路由,Generator 可直接生成 MapGet 调用。但要注意:Generator 看不到私有成员,也无法处理动态构造的类型名(如字符串拼接的类名)。

  • Generator 必须引用含特性的程序集,且该程序集不能是 InternalsVisibleTo 隐藏的
  • 特性类本身需为 public,且所有构造函数和属性也要是 public,否则 Generator 读不到值
  • 不要在特性中放不可序列化的字段(如委托、Stream),Generator 在编译期无法执行它们

实际项目里最常出问题的,是特性被定义成 internal 却期望在另一个程序集里被反射读到,或者忘了给 AttributeUsageInherited = true 导致子类方法拿不到父类标记的特性。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

258

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

38

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.9万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.2万人学习

Kotlin 教程
Kotlin 教程

共23课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号