网站首页 > 技术文章 正文
C# Attributes(属性)与反射读取
Attribute 简介
Attributes(属性)提供了一种有效方式,可以把元数据(metadata)和声明性信息(declarative information)与程序代码(assemblies, types, methods, properties 等等)关联起来。
通过 attributes 把元数据和程序里的实体(entity)关联以后,在程序运行过程中,通过反射(reflection),就可以查询到关联的 attributes,然后加以利用。
.Net 本身已经定义许多有用的 attributes,我们也可以定义自己的 attributes。
.Net 定义的 Attributes
先看几个 .Net 里面的 attributes:
- ObsoleteAttribute,标记程序实体已过时,不再使用,编译器会产生警告(或错误)。
- ConditionalAttribute,条件属性,编译根据条件是否符合,发出方法调用代码,或不发出。
- CLSCompliantAttribute,指示检查程序元素是否符合公共语言规范 (CLS)。如果开发的类库需要在多语言(如C#、VB.NET)环境下使用,这个检查很有帮助。
- FlagsAttribute,指示枚举可以当作位标志来对待,如枚举的值为:1、2、4、8、16、... 等。
下面是一个使用 ObsoleteAttribute 的代码片段例子。
下面是一个使用 ConditionalAttribute 的完整代码例子, 可以有选择性地注释掉最前面定义 CONDITION1、CONDITION2 的那两行, 然后重新编译运行程序,看程序输出有什么不同。
使用 Attribute 的场景举例:
- 在 Web 服务中,将控制器方法(controller methods)标志为 [ HttpPost ]
- 本机代码互操作的方法指定 [ MarshalAs(...) ]
- 使用于 Component Object Model (COM) 的类、方法、接口
- 调用非托管代码 [ DllImport(...) ]
- 描述程序集的标题、版本、描述、商标等信息
- 描述类成员的持久序列化
- 描述类成员序列化时和 xml 节点的映射关系
- 描述方法的安全要求
- 描述强制指定安全要求
- 控制编译器对即时编译(just-in-time)(JIT)的代码生成
- 获取调用者(caller)的信息
Attribute 语法
在 C#, 指定一个 attribute,把 attribute 名放在方括号 [ ] 中,放在要应用的实体前面。
依照惯例,attribute 的类名有后缀 "Attribute",但使用时则省略后缀。 例如:Serializable 的类名为 SerializableAttribute,使用名为 [Serializable]
(1)Attribute 的参数
许多 attributes 是带有参数的,可以按位置的、可以是命名的。
位置参数:
- 不能缺省
- 在参数列表中放在前面
- 顺序固定
命名参数:
- 可选的
- 要放在位置参数后面
- 顺序随意
Attributes 的参数类型限制为简单类型,bool、int、double、string、Type、enums等等,或者这些类型的数组。 而且要为字面量(literals)形式,不能使用表达式或变量。
(2)Attribute 的目标(target)
Attribute 的目标是 attribute 所应用于的实体。
语法:[target : attribute-list]
assembly | 整个程序集(assembly) |
module | 当前程序集的模块(module) |
field | 类或结构体中的字段 |
event | 事件(Event) |
method | 方法或 get 和 set 属性访问器(property accessors) |
param | 方法的参数或 set 属性访问器(property accessor)的参数 |
property | 属性(Property) |
return | 返回来自方法、属性索引器(property indexer)或 get 属性访问器(property accessor)的值 |
type | 结构体、类、接口、枚举或委托 |
创建自定义 Attributes
创建一个类,直接或间接从 System.Attribute 类派生。
使用AttributeUsageAttribute,来控制 attribute 允许目标类型(ValidOn)、是否对同一个实体应用多次(AllowMultiple)、是否允许继承(Inherited)。
下面是一个 attribute 继承(Inherited)的例子(代码片段):
下面是一个 attribute 应用多次(AllowMultiple)的例子(代码片段):
下面是一个 attribute 使用参数的例子(代码片段):
反射读取 Attributes
System.Type 类是反射的中心。
调用 Attribute 的 GetCustomAttribute 或 GetCustomAttributes 方法可获得关联的 attributes 信息。
Attribute 对象是“懒实例化”(instantiated lazily)的。 调用 GetCustomAttribute 或 GetCustomAttributes 时才实例化 Attribute 来返回, 并且每次返回的都是新实例化的,不是同一个对象。
下面是一个读取 attribute 的例子(代码片段):
总结
总而言之,Attributes 的特点可归纳如下:
- Attributes 给代码增加更多的元数据。虽然 .NET 本身已经有一套元数据了,包括类型和类型成员的元数据。 使用 attributes,可以额外添加自定义的元数据。
- Attributes 可以加到程序集(assemblies)、模块(modules)、类(classes )、属性(properties),等等。
- Attributes 可以接受参数。
- 程序可以通过反射,查询自己的 attributes,或其它程序的 attributes。
猜你喜欢
- 2025-07-27 pycharm下module 'requests' has no attribute 'get'问题的解决
- 2025-07-27 python委托定制超类getattr和getattribute管理属性
- 2025-07-27 「按键精灵安卓版」界面多选框实现10选3(选中不超过3个)
- 2025-07-27 Attribute Changer 11.30b属性更改器增强版
- 2025-07-27 关于Spring,必须要掌握的这25个常用注解,你知道几个?
- 2025-07-27 _attribute__((weak))关键字如何使用?
- 2025-07-27 Qt setAttribute设置窗口属性(qt设置窗口名)
- 2025-07-27 JSP request.setAttribute()详解及实例
- 2025-07-27 刘心向学(33):Python中的__getattr__与__getattribute__
- 2025-07-27 GNU __attribute详解(gnutls)
- 07-27据说这是1000年以后的课本(一千年后的教科书)
- 07-27穿得好,你也可以很丁真!黑黄皮男生夏日色彩搭配指南
- 07-27进口大众贰则 丨 Volkswagen Multivan T5与CrossGolf
- 07-27《病娇模拟器》制作人让玩家投票决定游戏的发展之路
- 07-27《呻吟》内容过于真实,请谨慎阅读(四)
- 07-27汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
- 07-27汇编语言mul乘法指令和模块化程序设计
- 07-27pycharm下module 'requests' has no attribute 'get'问题的解决
- 最近发表
-
- 据说这是1000年以后的课本(一千年后的教科书)
- 穿得好,你也可以很丁真!黑黄皮男生夏日色彩搭配指南
- 进口大众贰则 丨 Volkswagen Multivan T5与CrossGolf
- 《病娇模拟器》制作人让玩家投票决定游戏的发展之路
- 《呻吟》内容过于真实,请谨慎阅读(四)
- 汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
- 汇编语言mul乘法指令和模块化程序设计
- pycharm下module 'requests' has no attribute 'get'问题的解决
- python委托定制超类getattr和getattribute管理属性
- 「按键精灵安卓版」界面多选框实现10选3(选中不超过3个)
- 标签列表
-
- axure 注册码 (25)
- exploit db (21)
- mutex_lock (30)
- oracleclient (27)
- nfs (25)
- springbatch (28)
- oracle数据库备份 (25)
- dir (26)
- connectionstring属性尚未初始化 (23)
- output (32)
- panel滚动条 (28)
- centos 5 4 (23)
- sql学习 (33)
- c 数组 (33)
- pascal语言教程 (23)
- ppt 教程 (35)
- java7 (24)
- 自适应网站制作 (32)
- server服务自动停止 (25)
- 超链接去掉下划线 (34)
- 什么是堆栈 (22)
- map entry (25)
- ubuntu装qq (25)
- outputstreamwriter (26)
- fill_parent (22)