(一)在运行期间处理和检查代码

自定义特性允许把自定义元数据与程序元素关联起来。反射是一个普通术语,它描述了在运行过程中检查和处理程序元素的功能。例如,反射允许完成的任务:

  • 枚举类型的成员
  • 实例化新对象
  • 执行对象的成员
  • 查找程序集的信息
  • 检查应用于某种类型的自定义特性
  • 创建和编译新程序集

(二)自定义特性

使自定义特性非常强大的因素时使用反射,代码可以读取这些元数据,使用它们在运行期间作出决策。

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()等。

2、Assembly类

Assembly类在System.Reflection名称空间中定义,它允许访问给定程序集的元数据,它也包含可以加载和执行程序集(假定该程序集是可执行的)的方法。可以使用静态成员Assembly.Load()或Assembly.LoadFrom()。

使用Load()加载:

Assembly assembly1 = Assembly.Load("程序集名");

使用LoadFrom()加载:

Assembly assembly2 = Assembly.LoadFrom("程序集实际路径");

加载程序集后就可以使用它的各种属性进行查询:

string name = assembly1.FullName;

(1)获取在程序集中定义的类型的详细信息

Assembly类的一个功能是它可以获得在相应程序集中定义的所有类型的详细信息,只要调用Assembly.GetTypes()方法,就可以返回一个包含所有类型的详细信息的System.Type引用数组。

Type[] typeArray = assembly.GetTypes();

(2)获取自定义特性的详细信息

如果要确定程序集从整体上关联了什么自定义特性,就需要调用Attribute类的一个静态方法GetCustomAttributes()。

Attribute[] definedAttributes = Attribute.GetCustomAttributes(assembly);

【读书笔记】C#高级编程 第十五章 反射的更多相关文章

  1. 读书笔记 - js高级程序设计 - 第十五章 使用Canvas绘图

    读书笔记 - js高级程序设计 - 第十三章 事件   canvas 具备绘图能力的2D上下文 及文本API 很多浏览器对WebGL的3D上下文支持还不够好   有时候即使浏览器支持,操作系统如果缺缺 ...

  2. C#高级编程 第十五章 反射

    (二)自定义特性 使自定义特性非常强大的因素时使用反射,代码可以读取这些元数据,使用它们在运行期间作出决策. 1.编写自定义特性 定义一个FieldName特性: [AttributeUsage(At ...

  3. 【读书笔记】C#高级编程 第二十五章 事务处理

    (一)简介 事务的主要特征是,任务要么全部完成,要么都不完成. (二)概述 事务由事务管理器来管理和协调.每个影响事务结果的资源都由一个资源管理器来管理.事务管理器与资源管理器通信,以定义事务的结果. ...

  4. R in action读书笔记(20)第十五章 处理缺失数据的高级方法

    处理缺失数据的高级方法 15.1 处理缺失值的步骤 一个完整的处理方法通常包含以下几个步骤: (1) 识别缺失数据: (2) 检查导致数据缺失的原因: (3) 删除包含缺失值的实例或用合理的数值代替( ...

  5. 读书笔记 - js高级程序设计 - 第十二章 DOM2和DOM3

      Node类型的变化   访问元素的样式 myDiv.style.backgroundColor = "red" myDiv.style.width = "100px& ...

  6. 《java编程思想》读书笔记(一)开篇&第五章(1)

    2017 ---新篇章  今天终于找到阅读<java编程思想>这本书方法了,表示打开了一个新世界. 第一章:对象导论 内容不多但也有20页,主要是对整本书的一个概括.因为已经有过完整JAV ...

  7. R in action读书笔记(16)第十二章 重抽样与自助法之 置换检验

    第十二章:重抽样与自助法 本章,我们将探究两种应用广泛的依据随机化思想的统计方法:置换检验和自助法 12.1 置换检验 置换检验,也称随机化检验或重随机化检验. 有两种处理条件的实验,十个受试者已经被 ...

  8. R in action读书笔记(19)第十四章 主成分和因子分析

    第十四章:主成分和因子分析 本章内容 主成分分析 探索性因子分析 其他潜变量模型 主成分分析(PCA)是一种数据降维技巧,它能将大量相关变量转化为一组很少的不相关变量,这些无关变量称为主成分.探索性因 ...

  9. 【读书笔记】C#高级编程 第二十二章 安全性

    (一)身份验证和授权 安全性的两个基本支柱是身份验证和授权.身份验证是标识用户的过程,授权在验证了所标识用户是否可以访问特性资源之后进行的. 1.标识和Principal 使用标识可以验证运行应用程序 ...

随机推荐

  1. linux shell的配置文件执行顺序

    shell配置文件的作用:初始化环境变量.设置命令提示符.指定系统命令路径等 shell配置文件分类: (1)系统级别配置文件: /etc下,比如/etc/profile./etc/bashrc (2 ...

  2. 面试突击61:说一下MySQL事务隔离级别?

    MySQL 事务隔离级别是为了解决并发事务互相干扰的问题的,MySQL 事务隔离级别总共有以下 4 种: READ UNCOMMITTED:读未提交. READ COMMITTED:读已提交. REP ...

  3. 给妹子讲python-S01E01好用的列表

    1.python中的容器数据类型概述2.列表类型的异构性.有序性和本地可变性三大优势2.列表的基本操作(增.删.改.分片索引)3.列表的分片赋值与本地排序 [妹子说]今天开始学python啦,不过我们 ...

  4. 字节输入流_InputStream类&FileInputStream类介绍和字节输入流读取字节数据

    java.io.InputStream:字节输入流 此抽象类是表示字节输入流的所有类的超类 定义了所有子类共性的方法: int read()从输入流中读取数据的下一个字节 int read(byte[ ...

  5. Map集合概述和Map常用子类

    概述java.util.Map接口 Map<K,V> 有两个泛型 类型参数:K - 此映射所维护的键的类型V - 映射值的类型 特点:1.Map集合是双列集合,一个元素包含两个值,一个是k ...

  6. 在矩池云使用Disco Diffusion生成AI艺术图

    在 Disco Diffusion 官方说明的第一段,其对自身是这样定义: AI Image generating technique called CLIP-Guided Diffusion.DD ...

  7. Java开发学习(十一)----基于注解开发bean作用范围与生命周期管理

    一.注解开发bean作用范围与生命周期管理 前面使用注解已经完成了bean的管理,接下来将通过配置实现的内容都换成对应的注解实现,包含两部分内容:bean作用范围和bean生命周期. 1.1 环境准备 ...

  8. Idea Maven调试properties 找不到报错

    问题:maven执行package命令打包时,src/main/java路径下的properties文件偶尔丢失 解决方式:pom.xml中加入resources配置 <build> &l ...

  9. Note -「0/1 Fractional Programming」

    What is that? Let us pay attention to a common problem that we often meet in daily life: There are \ ...

  10. Python词频分析

    Python词频分析 一.前言 在日常工作或者生活中,有时候会遇到词频分析的场景.如果是要进行词频分析,那么首先需要对句子进行分词,将句子中的单词进行切割并按照词性进行归类. 在Python中有个第三 ...