概述反射
• 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象。
• 反射机制允许程序在执行过程中动态地添加各种功能。
运行时类型标识
•运行时类型标识(RTTI),可以在程序执行期间判定对象类型。例如使用它能够确切地知道基类引用指向了什么类型对象。
•运行时类型标识,能预先测试某个强制类型转换操作,能否成功,从而避免无效的强制类型转换异常。
•在c#中有三个支持RTTI的关键字:is 、 as 、typeof。 下面依次介绍他们
is运算符:
通过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 { }
</div>
as运算符:
在运行期间执行类型转换,并且能够使得类型转换失败不抛异常,而返回一个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 { }
</div>
typeof运算符:
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"); //打印
}