1.反射可以做什么?它可以动态创建对象,动态赋值,动态调用方法。
2..NET中的类都被编译成IL,反射可以再运行时获得类的信息。例如:获取哪些方法、字段、构造函数,父类等等,还可以动态创建对 象、调用成员。
3.每个类对应着一个Type对象,而每个方法对应着MethodInfo对象,每个属性对应一个PropertyInfo.这些就是类、方法、属性的“元数据”。这些“元数据对象”和成员有关,和对象无关,每个成员对应一个对象。
创建一个学生类:
public class Student { public Student(string name, int age,string sex) { this.name = name; this.age = age; this.sex = sex; } public Student(string sex) { this.sex = sex; } public Student() { } public int id; private string name; /// <summary> /// 姓名 /// </summary> public string Name { get { return name; } set { name = value; } } private int age; /// <summary> /// 年龄 /// </summary> public int Age { get { return age; } set { age = value; } } private string sex; /// <summary> /// 性别 /// </summary> public string Sex { get { return sex; } set { sex = value; } } public void Show() { Console.WriteLine("姓名:" + name + " " + "年龄:" + age + " " + "性别:" + sex); } }
获取该类的几种写法:
static void Main(string[] args)
{
Student student = new Student();
Type type1 = student.GetType(); Type type2 = typeof(Student); Type type3 = Type.GetType("ReflexDemo.Models.Student");
Console.WriteLine(object.ReferenceEquals(type1, type2));
Console.WriteLine(object.ReferenceEquals(type2, type3));
Console.ReadLine();
}
结果:
说明type1、type2、type3是同一个对象。
类的实例成员:在vs编译器中可以选择Type按F12进去看api文档
Type type = typeof(Student);
//BaseType该类型的父类
Console.WriteLine(type.GetType().BaseType.BaseType);
结果:
说明该类型父类的父类就是Type。
FieldInfo、PropertyInfo、MethodInfo、ConstructorInfo的父类和各种成员:
按F12我们可以看到FieldInfo、PropertyInfo都是继承MemberInfo。MethodInfo、ConstructorInfo继承MethodBase,而MemberInfo有是继承MethodBase。从而推出FieldInfo、PropertyInfo父类的父类就是MethodBase。
详细的类使用成员可以去查文档。
利用反射查看类中的属性:
/// <summary> /// 查看类中属性 /// </summary> public static void Properties() { Student Student = new Student();
//当前类中所有的公共属性 PropertyInfo[] infos = Student.GetType().GetProperties(); foreach (PropertyInfo pi in infos) { Console.WriteLine(pi.Name); } }
结果:
利用反射查看类中字段:
/// <summary> /// 类中字段 /// </summary> public static void Field() { Student Student = new Student();
//当前所有的公共字段 FieldInfo[] info = Student.GetType().GetFields(); foreach (FieldInfo fi in info) { Console.WriteLine(fi.Name); } }
结果:
利用反射获取类中的方法:
/// <summary> /// 类中方法 /// </summary> public static void Method() { Student Student = new Student();
//当前类中所有的公共方法 MethodInfo[] infos = Student.GetType().GetMethods(); foreach (MethodInfo mi in infos) { Console.WriteLine(mi.ReturnType + " " + mi.Name + " "); } #region 获取单个方法 MethodInfo info = Student.GetType().GetMethod("Show"); Console.WriteLine(info.ReturnType + " " + info.Name + " "); #endregion }
结果:
利用反射获取构造函数:
/// <summary> /// 反射构造函数 /// </summary> public static void Constructor() { Student Student = new Student(); Type type = Student.GetType(); //获取所有的公共构造函数 ConstructorInfo[] infos = type.GetConstructors(); foreach (ConstructorInfo ci in infos) { ParameterInfo[] parameterInfos = ci.GetParameters(); foreach (ParameterInfo pi in parameterInfos) { //参数类型和参数名称 Console.WriteLine(pi.ParameterType.ToString() + " " + pi.Name + " "); } } Console.ReadLine(); }
结果:
利用反射用构造函数生成对象:
/// <summary> /// 用构造函数生成对象 /// </summary> public static void ObjectPro() { Type type = typeof(Student); Type[] types = new Type[3]; types[0] = typeof(string); types[1] = typeof(int); types[2] = typeof(string); ConstructorInfo ci = type.GetConstructor(types); object[] obj = new object[3] { "Admin", 21, "男" }; #region 调用构造函数生成对象 object o = ci.Invoke(obj); #endregion #region 用Activator的CreateInstance静态方法,生成新对象 //object o = Activator.CreateInstance(type, obj); #endregion ((Student)o).Show(); }
结果:
反射类:
/// <summary> /// 反射类 /// </summary> public static void Assemblys() { Assembly assembly = Assembly.Load("ReflexDemo"); Type t = assembly.GetType("ReflexDemo.Models.Student"); //参数必须是类的全名 object o = Activator.CreateInstance(t, "男"); MethodInfo mi = t.GetMethod("Show"); //调用当前实例 mi.Invoke(o, null); }
结果:
反射DLL:首先你的dll文件要放到该项目的bin/Debug下面:
/// <summary> /// 反射DLL /// </summary> public static void AssmblysDll() { Assembly assembly = Assembly.LoadFrom("Newtonsoft.Json.dll"); Type[] tArray = assembly.GetTypes(); foreach (Type t in tArray) { Console.WriteLine(t.Name); } }
结果:
反射动态创建类:
/// <summary> /// 动态创建类 /// </summary> public static void OperationrRef() { Student Student = new Student(); Type t = Student.GetType(); //动态创建类,这个类必须要public且无参构造函数 object o = Activator.CreateInstance(t); FieldInfo info = t.GetField("id"); //给ID字段赋值 info.SetValue(o, 4); PropertyInfo propertyInfoName = t.GetProperty("Name"); //属性赋值 propertyInfoName.SetValue(o, "Admin", null); PropertyInfo propertyInfoAge = t.GetProperty("Age"); propertyInfoAge.SetValue(o, 18, null); PropertyInfo propertyInfoSex = t.GetProperty("Sex"); propertyInfoSex.SetValue(o, "男", null); MethodInfo memberInfo = t.GetMethod("Show"); memberInfo.Invoke(o, null); Console.WriteLine("ID为:" + ((Student)o).id); }
结果: