• 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 + "
    " + "年龄:" + 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);
            }

    结果:

  • 相关阅读:
    学会辨识「漏洞炒作」你就比别人强!
    Java 18 正式发布
    致敬Gif之父,使用Java生成Gif图片
    easyes的出现,江湖不再需要RestHighLevelClient
    机器学习科普摘录一
    RedMonk最新编程语言排行榜;Spring 框架现 RCE 漏洞……|叨资讯
    你该不会也觉得Dubbo参数回调中callbacks属性是用来限制回调次数的吧?
    甲骨文严查Java许可问题;黑客的多合一黑客工具|叨资讯
    Runtime Inline Cache
    Arthas之类操作
  • 原文地址:https://www.cnblogs.com/-zzc/p/12968625.html
Copyright © 2020-2023  润新知