C#高级编程 第十五章 反射
(二)自定义特性
使自定义特性非常强大的因素时使用反射,代码可以读取这些元数据,使用它们在运行期间作出决策。
1、编写自定义特性
定义一个FieldName特性:

- [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
- public class FieldNameAttribute : Attribute
- {
- private string name;
- public FieldNameAttribute(string name)
- {
- this.name = name;
- }
- }

(1)AttributeUsage特性
特性类本身用一个特性——System.AttributeUsage特性来标记。AttributeUsage第一个参数用于标识自定义特性可以应用到那些类型的程序元素上,其类型是枚举类型AttrubuteTargets。
当应用类型超过1个时,可以用OR运算符连接:
- [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
- AllowMultiple属性用于指定该特性是否可以多次应用于同一项上,当设置为false,以下编码会报错:
- [FieldName("我的属性1")]
- [FieldName("我的属性2")]
- public int MyProperty { get; set; }
- Inherited属性用于指示使用该特性的类或类成员能否由派生类或重写成员继承。
(2)指定特性参数
编译器会检查传递给特性的参数,并查找该特性中带这些参数的构造函数。一半仅提供一个构造函数,使用属性来定义任何其他可选参数。
(3)指定特性的可选参数
另一种语法,可把可选参数添加到特性中。这种语法指定可选参数的名称和值,它通过特性类中的公共属性或字段起作用。例如上述代码中AttributeUsage特性使用的AllowMultiple和Inherited就是使用的这种语法。
(三)反射
通过System.Type类可以访问关于任何数据类型的信息。System.Reflection.Assembly类可以用于访问给定程序集的相关信息,或者把这个程序集加载到程序中。
1、System.Type类
Type有与每种数据类型对应的派生类。获取指定任何给定类型的Type引用有3中常用方式:
使用C#的typeof运算符:
- Type type = typeof(double);
使用GetType()方法(所有的类都会从System.Object继承这个方法):
- double d = 10.0;
- Type type = d.GetType();
使用Type类的静态方法GetType():
- Type type = Type.GetType("System.Double");
(1)Type的属性

- 1 class Program
- 2 {
- 3 static void Main(string[] args)
- 4 {
- 5 Type intType = typeof(int);
- 6 Console.WriteLine("当前类型的类型名:"+intType.Name);
- 7 Console.WriteLine("当前类型的类型完全限定名:" + intType.FullName);
- 8 Console.WriteLine("当前类型的名称空间名:" + intType.Namespace);
- 9 Console.WriteLine("当前类型的直接基类名:" + intType.BaseType);
- 10 Console.WriteLine("当前类型的.NET运行库中映射到的类型:" + intType.UnderlyingSystemType);
- 11 Console.WriteLine("是否为数组的:" + intType.IsArray);
- 12 Console.WriteLine("是否为值类型:" + intType.IsValueType);
- 13 }
- 14 }
- 15 public class MyBaseClass { }
- 16 public class MyClass : MyBaseClass { }

运行以上代码,结果如下:
还有很多IsXXX来判断是否为某种类型。
(2)方法
System.Type类的大多数方法都用于获取对应数据类型的成员信息:构造函数、属性、方法和事件。后缀加‘s’的表示获取当前数据类型中所有的成员相关信息,不加则只获取数据类型中一个成员的相关信息。
- Type intType = typeof(int);
- var method = intType.GetMethod("GetHashCode");
- var methods = intType.GetMethods();
- foreach (var item in methods)
- {}
System.Type类还包含有GetConstructor()方法和GetConstructors()等
C#高级编程 第十五章 反射的更多相关文章
- 【读书笔记】C#高级编程 第十五章 反射
(一)在运行期间处理和检查代码 自定义特性允许把自定义元数据与程序元素关联起来.反射是一个普通术语,它描述了在运行过程中检查和处理程序元素的功能.例如,反射允许完成的任务: 枚举类型的成员 实例化新对 ...
- 【读书笔记】C#高级编程 第二十五章 事务处理
(一)简介 事务的主要特征是,任务要么全部完成,要么都不完成. (二)概述 事务由事务管理器来管理和协调.每个影响事务结果的资源都由一个资源管理器来管理.事务管理器与资源管理器通信,以定义事务的结果. ...
- UNIX:高级环境编程 - 第十五章 IPC:进程间通信
IPC(InterProcess Communication)进程间通信.为啥没有进程间通信,这是因为进程间都是同步的关系,不需要通信. 1.管道 1.1管道特点: (1)半双工的(即数据只能在一个方 ...
- 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图
读书笔记 - js高级程序设计 - 第十三章 事件 canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好 有时候即使浏览器支持,操作系统如果缺缺 ...
- 【读书笔记】C#高级编程 第二十二章 安全性
(一)身份验证和授权 安全性的两个基本支柱是身份验证和授权.身份验证是标识用户的过程,授权在验证了所标识用户是否可以访问特性资源之后进行的. 1.标识和Principal 使用标识可以验证运行应用程序 ...
- 【读书笔记】C#高级编程 第十九章 程序集
(一)程序集的含义 程序集是.NET用于部署和配置单元的术语. .NET应用程序包含一个或多个程序集.通常扩展名是EXE或DLL的.NET可执行程序称为程序集. 程序集是自我描述的安装单元,由一个或多 ...
- 【读书笔记】C#高级编程 第十六章 错误和异常
(一)简介 错误的出现并不总是编写应用程序的人的原因,有时应用程序会因为应用程序的最终用户引发或运行代码的环境而发生错误.C#提供了异常处理机制来处理错误. (二)异常类 在C#中,但刚出现某个特殊的 ...
- Windows核心编程 第十五章 在应用程序中使用虚拟内存
第1 5章 在应用程序中使用虚拟内存 Wi n d o w s提供了3种进行内存管理的方法,它们是: • 虚拟内存,最适合用来管理大型对象或结构数组. • 内存映射文件,最适合用来管理大型数据流(通常 ...
- 【读书笔记】C#高级编程 第二十四章 文件和注册表操作
(一)文件和注册表 对于文件系统操作,相关的类几乎都在System.IO名称空间中,而注册表操作由System.Win32名称空间中的类来处理. (二)管理文件系统 System.MarshalByR ...
随机推荐
- linux内核之情景分析mmap操作
进程可以通过mmap把一个已打开文件映射到用户空间. mmap(void*start,size_t length,int prot,int flags,int fd,off_t offset) sta ...
- python:virtualenv的使用
安装virtualenv 使用pip安装:pip install virtualenv virtualenvwrapper 其中virtualenvwrapper是virtualenv的扩展工具,用于 ...
- 【原创】打开Excel时提示"您尝试打开的文件**.xls的格式与文件扩展名指定的格式不一致"
问题描述: 系统安装了WPS时,Analyzer导出excel时候,会提示"您尝试打开的文件**.xls的格式与文件扩展名指定的格式不一致",这是Excel的安全问题, ...
- nodejs编写实例基础操作
学习视频地址 https://cnodejs.org/topic/5a72c66ace45d440451465c3 初始化项目 首先查看项目中是否有package.json 文件,如果有可执行np ...
- TopCoder SRM 301 Div2 Problem 1000 CorrectingParenthesization(区间DP)
题意 给定一个长度为偶数的字符串.这个字符串由三种括号组成. 现在要把这个字符串修改为一个符合括号完全匹配的字符串,改变一个括号的代价为$1$,求最小总代价. 区间DP.令$dp[i][j]$为把子 ...
- addEventListener与attachEvent
一.attachEvent和addEventListener (一)addEventListener addEventListener() 方法用于向指定元素添加事件句柄.使用 removeEvent ...
- Java开发笔记(一百零四)普通线程池的运用
前面介绍了线程的基本用法,以及多线程并发的问题处理,但实际开发中往往存在许多性质相似的任务,比如批量发送消息.批量下载文件.批量进行交易等等.这些同类任务的处理流程一致,不存在资源共享问题,相互之间也 ...
- 检查iOS app 是否升级为新版本
之前我帮某公司做的一个iOS app,升级的时候发现闪退问题.后来检查是因为升级的时候数据库出现一点小问题导致对象为空. 下面这个代码可以检测程序是否更新了,从而进行相关处理: 1 2 3 4 5 6 ...
- xamarin.android 资源图片问题
在xamarin.android 中,关于图片的资源一般都在Resources.drawable下面,在Resources这个文件夹下面,包含了drawable.drawale-hdpi.drawab ...
- 分治法寻找第k大的数
利用快速排序的思想·去做 #include<iostream>using namespace std;int FindKthMax(int*list, int left, int righ ...