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 + "\n" + "年龄:" + age + "\n" + "性别:" + 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 + "\n" + mi.Name + "\n");
}
#region 获取单个方法
MethodInfo info = Student.GetType().GetMethod("Show");
Console.WriteLine(info.ReturnType + "\n" + info.Name + "\n");
#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() + "\n" + pi.Name + "\n");
}
}
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);
}
结果: