定义
反射(Reflection)是指程序可以访问、检测、修改它本身的状态和行为的一种能力
反射提供程序集、模块和类型的对象
优点
反射可以提供程序的灵活性和扩展性
可以降低耦合,提高自适应能力
它允许程序创建和控制任何类对象,不需要提前硬编码类
缺点
性能问题,反射的使用类似于一种解释操作,使用反射获取字段和方法时要比直接源代码慢很多
使用反射会模糊程序内部代码逻辑,当程序出行bug时,我们更加希望直接从源代码看到程序的逻辑,而使用反射是在运行时进行创建和控制的,我们无法直接看到源代码
使用场景
在运行时需要创建新的对象
执行后期绑定,访问在运行时创建的类型方法
主要用途
Assembly:定义和加载程序集
FieldInfo:加载数据成员对象
MethodInfo:加载函数成员对象
GetType与typeof
GetType是继承自Object类的一个方法,可以返回一个变量的类型对象(Type),即其使用方法为:变量名.GetType();
typeof()方法使用方法为typeof(x),其中x只能是具体的类型名称,如int float等等不能是变量,typeof中填什么类型就返回什么类型
示例
class Program
{
class Test
{
public int num;
public Test() { }
public Test(int num)
{
this.num = num;
}
public void TestMethod1()
{
Console.WriteLine("TestMethod1");
}
public void TestMethod2(int num)
{
this.num = num;
Console.WriteLine("TestMethod2");
}
}
static void Main(string[] args)
{
Test t1 = new Test(1);
Type ty1 = t1.GetType();//通过GetType获取对象类型
Type ty2=typeof(Test); //通过typeof获取对象类型
Console.WriteLine(ty1==ty2);
//通过反射创建对象
object obj1 = Activator.CreateInstance(ty1);
Console.WriteLine(obj1.GetType());
//获取数据成员
FieldInfo[] f1=ty1.GetFields();
foreach(var item in f1)
{
Console.WriteLine(item);
}
//通过GetField获取数据成员 通过SetValue修改数据成员,GetValue获取
FieldInfo info1 = ty1.GetField("num");
info1.SetValue(obj1,2);
Console.WriteLine(info1.GetValue(obj1));
Console.WriteLine((obj1 as Test).num);
//通过GetMethod访问无参函数
MethodInfo minfo1 = ty1.GetMethod("TestMethod1");
minfo1.Invoke(obj1,null);
//通过GetMethod访问带参函数
MethodInfo minfo2 = ty1.GetMethod("TestMethod2");
//使用bject类型的数组去存储函数的参数值
object[] parameters = new object[1];
parameters[0] = 1;//这里可以说是一个装箱
minfo2.Invoke(obj1,parameters);
Console.WriteLine(info1.GetValue(obj1));
}
}