详解C#特性和反射(一)
使用特性(Attribute)可以将描述程序集的信息和描述程序集中任何类型和成员的信息添加到程序集的元数据和IL代码中,程序可以在运行时通过反射获取到这些信息;
一、通过直接或间接的继承自抽象类System.Attribute可以创建自定义的特性类,自定义的特性类必须声明为公共类,命名一般使用Attribute结尾以保证可读性,自定义特性可以附加到大多数元素声明中,也可以使用特性System.AttributeUsage(该特性只能用于特性类声明)指定该特性所能生效的范围及其它特性特征参数:
[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
//其中,枚举组合AttributeTargets指定该特性生效的范围,默认为All即所有范围;
//布尔值Inherited指定应用该特性的成员在派生类中是否会继承该特性,默认为true;
//布尔值AllowMultiple指定能否为同一个元素指定多个此特性,默认为false
public class MyselfAttribute : Attribute
{
public string ClassName { get; private set; }
public string Author; public MyselfAttribute(string className)
{
this.className = className;
}
}
其中特性类的构造函数中的参数称为位置参数(Positional Parameters),类中的其他公共字段和属性称为命名参数(Named Parameter), 通常情况下,将所有必选的参数定义为位置参数,将所有可选的参数定义为命名参数;特性类和普通类一样可以进行构造函数的重载以适应各种情况下初始化参数的组合使用;
二、使用特性时,通过方括号[]将特性名称括起来,并置于使用该特性的元素声明的上方或前方以指定特性,使用时可以省略Attribute后缀,根据想要初始化时调用特性类构造函数的不同,需要将该构造函数所需的参数(即位置参数)的值按照顺序传入,还可以选择是否指定命名参数的值,命名参数的值通过赋值运算符=显式指定:
[Myself("MyClass", Author = "Me")]
//这个声明在概念上等效于:
//MyselfAttribute myselfObj = new MyselfAttribute("MyClass");
//myselfObj.Author = "Me";
//[Myself("MyClass", Author = "You")] //特性Myself可以对同一元素指定多次
//也可以将多个特性合并在一个方括号里:
//[Myself("MyClass", Author = "Me"), Myself("MyClass", Author = "You")]
public class MyClass
{
public void MyFunc([Myself("MyParameter")]int myNum) //在方法参数列表中给参数指定特性
{
//do…
}
}
经过编译后,在元数据中查看到的类型定义中的特性信息:
TypeDef # ()
-------------------------------------------------------
TypDefName: MyClass ()
Flags : [Public] [AutoLayout] [Class] [AnsiClass] [BeforeFieldInit] ()
Extends : [TypeRef] System.Object
Method # ()
-------------------------------------------------------
MethodName: MyFunc ()
Flags : [Public] [Virtual] [HideBySig] [NewSlot] (000001c6)
RVA : 0x00002050
ImplFlags : [IL] [Managed] ()
CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
Arguments
Argument #: I4
Parameters
() ParamToken : () Name : myNum flags: [none] ()
CustomAttribute # (0c000003)
-------------------------------------------------------
CustomAttribute Type:
CustomAttributeName: MyselfAttribute :: instance void .ctor(class System.String)
Length:
Value : 0b 4d 6d > MyParameter <
ctor args: ("MyParameter") Method # ()
-------------------------------------------------------
MethodName: .ctor ()
Flags : [Public] [HideBySig] [ReuseSlot] [SpecialName] [RTSpecialName] [.ctor] ()
RVA : 0x0000205a
ImplFlags : [IL] [Managed] ()
CallCnvntn: [DEFAULT]
hasThis
ReturnType: Void
No arguments. CustomAttribute # (0c000015)
-------------------------------------------------------
CustomAttribute Type:
CustomAttributeName: MyselfAttribute :: instance void .ctor(class System.String)
Length:
Value : 4d 6c 0e > MyClass T A<
: 6f 4d >uthor Me <
ctor args: ("MyClass")
在IL代码中查看到的类型定义中的特性信息:

三、系统预定义的一些常用特性:

四、特性通常配合反射起作用,在指定的时机通过反射获得自定义特性并对其进行操作,具体内容在下一章中介绍;
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!
作者:Minotauros
出处:https://www.cnblogs.com/minotauros/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
详解C#特性和反射(一)的更多相关文章
- EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象
EF+LINQ事物处理 在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...
- 详解C#特性和反射(四)
本篇内容是特性和反射的最后一篇内容,前面三篇文章: 详解C#特性和反射(一) 详解C#特性和反射(二) 详解C#特性和反射(三) 一.晚期绑定(Late Binding)是一种在编译时不知道类型及其成 ...
- 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码
详解C#泛型(二) 一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...
- 详解C#特性和反射(三)
类型信息(Type Information)用来表示类型声明的信息,通过抽象基类System.Type的实例存储这些信息,当使用反射时,CLR获取指定类型的Type对象,通过这个对象即可访问该类型的任 ...
- 详解C#特性和反射(二)
使用反射(Reflection)使得程序在运行过程中可以动态的获取对象或类型的类型信息,然后调用该类型的方法和构造函数,或访问和修改该类型的字段和属性:可以通过晚期绑定技术动态的创建类型的实例:可以获 ...
- 【转】详解C#中的反射
原帖链接点这里:详解C#中的反射 反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...
- 详解Java8特性之新的日期时间 API
详解Java8特性之新的日期时间 API http://blog.csdn.net/timheath/article/details/71326329 Java8中时间日期库的20个常用使用示例 ht ...
- Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用
一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...
- 详解C#中的反射
反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B ...
随机推荐
- jQuery插件实践之轮播练习(二)
所有文章搬运自我的个人主页:sheilasun.me 上一篇中学习了jQuery插件的写法,这篇该着手实现啦.首先明确一下轮播要具备哪些功能: 可以点击"向后"按钮向后翻页 可以点 ...
- openstack网络服务Neutron(六)
一.Neutron控制节点安装 1.Neutron安装 [root@linux-node1 ~]# yum install -y openstack-neutron openstack-neutron ...
- P1219 八皇后 含优化 1/5
题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 ...
- 【Java】 剑指offer(15) 数值的整数次方
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 实现函数double Power(double base, int ...
- 【Java】 剑指offer(34) 二叉树中和为某一值的路径
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有 ...
- bfs-poj3278
题目链接:http://poj.org/problem?id=3278 题意:农夫原始在N位置上,他的目的是要抓到在K位置上的牛.牛的位置是固定不变的,而农夫的移动是在一条水平线上进行的,移动方式有以 ...
- 极客无极限 一行HTML5代码引发的创意大爆炸
摘要:一行HTML5代码能做什么?国外开发者Jose Jesus Perez Aguinaga写了一行HTML5代码的文本编辑器.这件事在分享到Code Wall.Hacker News之后,引起了众 ...
- nodejs那些事儿
http://www.nodeclass.com/ https://cnodejs.org/ 当前版本,v6.11.2 安装node时,牵扯features的选择,在不了解的情况下,我选择了第1个.网 ...
- Winform给TextBox设置默认值
Winform给TextBox设置默认值(获取焦点后默认值消失) 主要是通过TextBox的获取焦点Enter和失去焦点Leave两个事件来实现的, 思路如下: 1.设置一个字符串常量,作为TextB ...
- [NOIp2012提高组]同余方程
OJ题号: 洛谷1082 思路: 逆元模板. #include<cstdio> #include<cctype> inline int getint() { char ch; ...