使用特性(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#特性和反射(一)的更多相关文章

  1. EF+LINQ事物处理 C# 使用NLog记录日志入门操作 ASP.NET MVC多语言 仿微软网站效果(转) 详解C#特性和反射(一) c# API接受图片文件以Base64格式上传图片 .NET读取json数据并绑定到对象

    EF+LINQ事物处理   在使用EF的情况下,怎么进行事务的处理,来减少数据操作时的失误,比如重复插入数据等等这些问题,这都是经常会遇到的一些问题 但是如果是我有多个站点,然后存在同类型的角色去操作 ...

  2. 详解C#特性和反射(四)

    本篇内容是特性和反射的最后一篇内容,前面三篇文章: 详解C#特性和反射(一) 详解C#特性和反射(二) 详解C#特性和反射(三) 一.晚期绑定(Late Binding)是一种在编译时不知道类型及其成 ...

  3. 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码

    详解C#泛型(二)   一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...

  4. 详解C#特性和反射(三)

    类型信息(Type Information)用来表示类型声明的信息,通过抽象基类System.Type的实例存储这些信息,当使用反射时,CLR获取指定类型的Type对象,通过这个对象即可访问该类型的任 ...

  5. 详解C#特性和反射(二)

    使用反射(Reflection)使得程序在运行过程中可以动态的获取对象或类型的类型信息,然后调用该类型的方法和构造函数,或访问和修改该类型的字段和属性:可以通过晚期绑定技术动态的创建类型的实例:可以获 ...

  6. 【转】详解C#中的反射

    原帖链接点这里:详解C#中的反射   反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子: 1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内 ...

  7. 详解Java8特性之新的日期时间 API

    详解Java8特性之新的日期时间 API http://blog.csdn.net/timheath/article/details/71326329 Java8中时间日期库的20个常用使用示例 ht ...

  8. Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用

    一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...

  9. 详解C#中的反射

    反射(Reflection) 2008年01月02日 星期三 11:21 两个现实中的例子:1.B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况.这是如何做到的呢?B超是B ...

随机推荐

  1. springbank 开发日志 Spring启动过程中对自定义标签的处理

    这篇随笔的许多知识来源于:http://www.importnew.com/19391.html 之所以会去看这些东东,主要是希望能够模仿spring mvc的处理流程,做出一套合理的交易处理流程. ...

  2. 080 HBase的属性

    一:基本属性 1.查看属性 2.解释属性 NAME:列簇名 BLOOMFILTER:布隆过滤器,用于对storefile的过滤 共有三种类型: ROW:行健过滤 ROWCOL:行列过滤 NONE:无 ...

  3. Unity 之 中文乱码

    更改 C#脚本的编码格式: 文件 -> 高级保存选项 -> Unicode

  4. PropertyUtils.copyProperties(); java.lang.NullPointerException可能产生的原因

    PropertyUtils.copyProperties(Object dest, Object orig); 出现空指针异常可能产生的原因(不一定准确):java.lang.NullPointerE ...

  5. jstl标签比较格式化后的时间

    c:set 里面不支持任何标签,这样写不好讲格式化的值放到bdateVar里面 <c:set var="bdateVar" value="<fmt:forma ...

  6. mac下配置Apache虚拟域名方案,以及遇到的坑(转)

      1. 配置Apache虚拟域名 1.执行    sudo vi /etc/apache2/httpd.conf 开始配置httpd.conf 的文件; //配置listen 80端口(默认配置), ...

  7. webstorm 格式化代码及常用快捷键

    mac 下 webstorm 格式化代码的快捷键 Option+Command+l windows 下 webstorm 格式化代码的快键键 Ctrl+Alt+l centOS 下webstorm 格 ...

  8. 一道有意思的多线程面试题 C# 代码实现

    如果你对多线程的控制不怎么了解,那么理解了这篇文章的内容也许对你有帮助.鼓励先自己动手实现一遍,做不出来在看代码. 题目一:两个线程交替打印0~100的奇偶数 这道题就是说有两个线程,一个名为偶数线程 ...

  9. Django 学习第二天——URL路由及模板渲染方式

    URL 的概念及格式: URL的引入:客户端:知道了url 就可以去进行访问: 服务端:设置好了url,别人才能访问到我 URL :网址(全球统一资源定位符):由 协议,域名(ip port) ,路径 ...

  10. 安装Appium-desktop,并连接模拟器!Appium-Python-Client

    1.下载appium-desktop https://github.com/appium/appium-desktop/releases 2.双击 exe 文件,然后,等待安装完就好了 3.启动app ...