通过is运算符,能够判断对象类型是否为特定类型,如果两种类型是相同类型,或者两者之间存在引用,装箱拆箱转换,则表明两种类型是兼容的。
class PRogram { static void Main(string[] args) { A a = new A(); B b = new B(); if (a is A) { Console.WriteLine("a is an A"); //这个打印,因为a 是 A 类型的对象 } if (b is A) { //这个打印,因为b是B类型的对象,而B类型派生于A类型,由于b对象可以转换为A类型,因此b对象与A类型是兼容的,但是反过来就不成立,例如下面不打印 Console.WriteLine("b is an A because it is derived from"); } if (a is B) { //这个不打印 Console.WriteLine("This won't display , because a not derived from B"); } if (a is object) { //这个打印 Console.WriteLine("a is an object"); } Console.ReadKey(); } } class A { } class B : A { }
在运行期间执行类型转换,并且能够使得类型转换失败不抛异常,而返回一个null值,其实as也可以看作一个is运算符的简化备选方式(看例子)。
class Program    {        static void Main(string[] args)        {            A a = new A();            B b = new B();            if (a is B)            {                b = (B)a;   //由于a变量不是B类型,因此这里将a变量转换为B类型是无效的。            }            else            {                b = null;            }            if (b ==null)            {                //这个打印                Console.WriteLine("The cast in b=(B)a is not allowed");             }            //上面使用as运算符,能够把两部合二为一。            b = a as B;   //as类型先检查强制类型转换的有效性,如果有效,则执行强类型转换过程。这些都在这一句完成。            if (b == null)            {                //这个打印                Console.WriteLine("The cast in b=(B)a is not allowed");            }            Console.ReadKey();        }    }    class A { }    class B : A { }as ,is 能够测试两种类型的兼容性。但大多数情况下,还需要获得某个类型的具体信息。这就用到了typeof,它可以返回与具体类型相关的System.Type对象,通过System.Type对象可以去顶此类型的特征。一旦获得给定类型的Type对象,就可以通过使用该对象定义的各种属性,字段,方法来获取类型的具体信息。Type类包含了很多成员,在接下来的反射中再详细讨论。下面简单的演示Type对象,调用它的三个属性。
static void Main(string[] args)        {            Type t=typeof(StringBuilder);            Console.WriteLine(t.FullName);  //FullName属性返回类型的全称            if (t.IsClass)            {                Console.WriteLine("is a class"); //打印            }            if (t.IsSealed)  //是否为密封类            {                Console.WriteLine("is Sealed");  //打印            }            Console.ReadKey();        }| MemberInfo类中的只读属性 | |
| 属性 | 描述 | 
| TypeDeclaringType | 获取声明该成员的类或接口的类型 | 
| MemberTypesMemberType | 获取成员的类型,这个值用于指示该成员是字段、方法、属性、事件、或构造函数 | 
| IntMetadataToken | 获取与特定元数据相关的值 | 
| ModuleModule | 获取一个代表反射类型所在模块(可执行文件)的Module对象 | 
| StringName | 成员的名称 | 
| TypeReflectedType | 反射的对象类型 | 
请注意
当然除了MemberInfo类定义的方法和属性外,Type类自己也添加了许多属性和方法:如下表(只列出一些常用的,太多了,自己可以转定义Type类看下)
| Type类定义的方法 | |
| 方法 | 功能 | 
| ConstructorInfo[] GetConstructors() | 获取指定类型的构造函数列表 | 
| EventInfo[] GetEvents(); | 获取指定类型的时间列 | 
| FieldInfo[] GetFields(); | 获取指定类型的字段列 | 
| Type[] GetGenericArguments(); | 获取与已构造的泛型类型绑定的类型参数列表,如果指定类型的泛型类型定义,则获得类型形参。对于正早构造的类型,该列表就可能同时包含类型实参和类型形参 | 
| MemberInfo[] GetMembers(); | 获取指定类型的成员列表 | 
| MethodInfo[] GetMethods(); | 获取指定类型的方法列表 | 
| PropertyInfo[] GetProperties(); | 获取指定类型的属性列表 | 
下面列出Type类定义的常用的只读属性
| Type类定义的属性 | |
| 属性 | 功能 | 
| Assembly Assembly | 获取指定类型的程序集 | 
| TypeAttributes Attributes | 获取制定类型的特性 | 
| Type BaseType | 获取指定类型的直接基类型 | 
| String FullName | 获取指定类型的全名 | 
| bool IsAbstract | 如果指定类型是抽象类型,返回true | 
| bool IsClass | 如果指定类型是类,返回true | 
| string Namespace | 获取指定类型的命名空间 | 
上面的列术都是为了,这里的使用。
通过使用Type类定义的方法和属性,我们能够在运行时获得类型的各种具体信息。这是一个非常强大的功能。我们一旦得到类型信息,就可以调用其构造函数,方法,和属性。可见,反射是允许使用编译时不可用的代码的。
由于Reflection API非常多,这里不可能完整的介绍他们(这里如果完整的介绍,据说要一本书,厚书)。但是,Reflection API是按照一定逻辑设计的。因此,只要知道部分接口的使用方法,就可以举一反三的使用剩余的接口。
这里我列出四种关键的反射技术:
一旦有了Type对象就可以使用GetMethodInfo()方法获取此类型支持的方法列表。该方法返回一个MethodInfo 对象数组,MethodInfo对象描述了主调类型所支持的方法,他位于System.Reflection命名空间中
     MethodInfo类派生于Method
新闻热点
疑难解答