一:什么是反射?反射能干什么?
1.反射是一种能力,所以给的定义就是说明了它能干什么
2.获取类型相关的信息;动态的调用方法;动态构造对象;从程序集中获得类型
a:获取类型相关的信息:反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息(方法,字段,属性,事件);
直接使用typeof操作符 Type T1 = typeof(StringBuilder);
通过类型实例 Type T2 = new StringBuilder().GetType();
通过Type类的静态方法 Type T3 = Type.GetType("System.IO.Stream");
b:获取类型本身信息(命名空间,全名,是否是抽象,是否是类)
var T1 = typeof(StringBuilder);
Console.WriteLine("命名空间名称:"+T1.Namespace);
Console.WriteLine("直接基类型",T1.BaseType);
Console.WriteLine("全名",T1.FullName);
Console.WriteLine("是否是抽象类型",T1.IsAbstract);
Console.WriteLine("是类",T1.IsClass);
c:获取类型成员的信息
Type T1 = typeof(TClass);
var Mets = T1.GetMembers();
foreach(var m in Mets)
{
Console.WriteLine(m.MemberType()+":"+m.Name);
}
d:动态调用方法:
首先自定义一个类
public class TClass
{
public void fun(string str)
{
Cosole.WriteLine("我是fun方法,我被调用了",str);
}
public void fun2()
{
Console.WriteLine("我是fun2方法,我被调用了");
}
public void static fun3()
{
Console.WriteLine("我是fun3方法,我被调用了");
}
}
A:调用方式一(使用InvokeMember调用方法)
调用带参数的实例方法fun()
Type T1 = typeof(TClass);
T1.InvokeMember("fun",BindingFlags.InvokeMethod,null,new TClass(),new string[]{"test"});
调用无参数实例方法fun2()
Type T1 = typeof(TClass);
T1.InvokeMember("fun3",BindingFlags.InvokeMethod,null,new TClass(),null);
调用静态方法
Type T1 = typeof(TClass);
T1.InvokeMember("fun3",BindingFlags.InvokeMethod,null,T1,null);
注意:当我们调用实例方法的时候需要传实例对象过去。在我们实例了对象后,任然不确定调用哪个方法时可以只有使用,
如果实例对象也不确定,接着往下看
第一个:要被动态调用的方法名。
第二个:是一个枚举,表示调用一个方法
第三个:是Binder,传的是null,使用默认值。
第四个:传如实例对象(调用实例方法时)或者Type对象(调用静态方法时)
第五个:要传给被调用发的参数数组
B:调用方式二(使用MethodInfo.Invoke调用方法)
Type T1 = typeof(TClass);
T1.GetMethod("fun",BindingFlags.Instance|BindingFlages.Public).Invoke(new TClass(),new string[]{"testfun1"});
T1.GetMethod("fun2",BindingFlags.Instance|BindingFlages.Public).Invoke(new TClass(),null);
T1.GetMethod("fun3",BindingFlags.Static|BindingFlages.Public).Invoke(T1,null);
C:正真的全动态调用
Console.WriteLine("请输入对象类名");
string className = Console.ReadLine();
Console.WriteLine("请输入要执行的方法名");
string funName = Console.ReadLine();
Type T1 = Type.GetType(className);
ConstructorInfo ci = T1.GetConstructors()[0]; //获取构造函数
var obj = ci.Invoke(null); //实例化构造函数
T1.InvokeMember(funName,BindingFlags.InvokeMethod,null,obj,null);
d:动态构造对象
先定义一个对象
public class TClass
{
public TClass()
{
Console.WriteLine("构造函数被执行了");
}
public TClass(string str)
{
Console.WriteLine("有参数的构造函数被执行了"+str);
}
}
动态构造对象
//动态构造对象,方式一
Assembly as, = Assembly.GetExecutingAssembly();
TClass obj = (TClass).asm.CreateInstance("net.tclass",true);
//动态构造对象,方式二
ObjectHandle handler = Activator.CreateInstance(null,"net.TClass");
obj = (TClass)handler.Unwrap();
//动态构造函数,方式三
Assembly asm2 = Assembly.GetExecutingAssembly();
obj = (TClass)asm2.CreateInstance("net.tclass",true,BindingFlages.Default,null,new string[]{"test"},null,null);
获取和修改属性
var obj = new TClass();
obj.name = "张三";
Type type = typeof(TClass);
//获取属性
var Name = type.InvokeMember("name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null,
obj, new object[] { }) as string;
Console.WriteLine(obj.name);
//设置属性
type.InvokeMember("name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null,
obj, new object[] { "新属性(李四)" });
Console.WriteLine(obj.name);
//=====================
PropertyInfo[] pros = type.GetProperties(---);//
PropertyInfo pro = null;
var value = pro.GetValue(type);//获取值
e:从程序集里获得类型
取得当前代码所在程序集
Assembly ass = Assembly.GetExecutingAssembly();
Console.WriteLine("当前所在程序集名:"+ass.ManifestModule.Name);
Console.WriteLine("当前所在程序集路径:"+ass.Location);
总结:反射不是某一个概念,而是一类操作的统称。或者说是某些能力的统称,它能动态调用对象方法,动态读取和设置属性和字段,它能动态加载程序外的dll。
看你想要什么样的薪资。(和工作年限无关)
如果要月薪五位数的话,反射、多线程、委托事件、设计模式一般都会在面试的时候问到。
就算不一定每次面试都会问到,那也是你必须要知道的。
原文地址:https://www.cnblogs.com/HansZimmer/p/9299380.html