> 文章列表 > C#基础学习--反射和特性

C#基础学习--反射和特性

C#基础学习--反射和特性

元数据和反射

要使用反射,必须使用System.Reflection 命名空间

 Type类

Type是一个抽象类,用来包含类型特性,使用这个类的对象可以让我们获取程序使用的类型的信息

 我们可以从Type对象中获取需要了解的有关类型的几乎所有信息

获取Type对象

object 类型包含了一个叫做GetType 的方法,它返回对实例的Type对象的引用。

  Type  t = myInstance.GetType();

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;  //必须使用的命名空间namespace Csharpzuoye
{class BaseClass{public int BaseField = 0;}class DerivedClass:BaseClass{public int DrivedFiled = 0;}class Program{static void Main(){var bc = new BaseClass();var dc = new DerivedClass();BaseClass[] bca = new BaseClass[] { bc, dc };foreach(var v in bca){Type t = v.GetType();  //获取类型Console.WriteLine("Object type: {0}", t.Name);FieldInfo[] fi = t.GetFields();  //获取字段数据foreach (var f in fi)Console.WriteLine("     Field : {0}", f.Name);Console.WriteLine();}}}
}

 我们可以使用typeof运算符来获取Type对象。只需要提供类型名作为操作数,它就会返回Type对象的引用

 什么是特性

特性是一种允许我们向程序的程序集增加元数据的语言结构。它是用于保存程序结构信息的某种特殊类型的类

 应用特性

特性的目的是告诉编译器把程序结构的某组元数据嵌入程序集。我们可以通过把特性应用到结构来实现

预定义的保留的特性

在学习如何定义自己的特性之前,先介绍几个.NET 预定义特性

Obsolete 特性

可以使用Obsolete特性将程序结构标注为过期的,并且在代码编译时显示有用的警告信息

Conditional 特性

Conditional 特性允许我们包括或排斥特定方法的所有调用。

 调用者信息特性

调用者信息特性可以访问文件路径,代码行数,调用成员的名称等源代码信息

 DeBuggerStepThrough特性

我们在单步调试代码时,常常希望调试器不要进入某些方法。DeBuggerStepThrough特性告诉调试器在执行目标代码时不要进入其中调试而是直接执行

其他预定义特性

这里使用的是不带 Attribute 后缀的短名称

 有关应用特性的更多内容

多个特性

我们可以为单个结构应用多个特性

 其他类型的目标

除了类还可以将特性应用到诸如字段和属性等其他程序结构

 全局特性

自定义特性

特性只是某个特殊类型的类

声明自定义特性

总体来说,声明一个特性类和声明其他类一样

使用特性的构造函数

指定构造函数

当我们为目标应用特性时,其实是在指定应该使用哪个构造函数来创建特性的实例。列在特性应用中的参数其实就是构造函数的参数

使用构造函数 

我们不能显式调用构造函数,特性的实例创建后,只有特性的消费者访问特性时才能调用构造函数。应用一个特性时一条声明语句,它不会决定什么时候构造特性类的对象

构造函数中的位置参数和命名参数

 和普通类的方法与构造方法类似,特性的构造方法同样可以使用位置参数和命名参数

 

 构造函数需要的任何位置参数都必须放在命名参数之前

限制特性的使用  AttributeUsage特性

有一个很重要的预定义特性可以用来应用到自定义特性上,那就是AttributeUsage 特性,我们可以用它来限制特性使用在某个目标类型上