C#反射

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);
        }

结果:

 

posted @ 2020-05-27 22:25  zero219  阅读(237)  评论(0编辑  收藏  举报