zoukankan      html  css  js  c++  java
  • 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);
            }

    结果:

  • 相关阅读:
    LEFT JOIN个别问题
    phporjquery生成二维码
    杂项(乌班图、flex的使用实例)
    mysql创建用户并授权,解决1045
    jar运行指定jdk
    Flutter升级版本后,运行项目报错
    spring boot执行jar包指定active profile
    centos7 安装clamav 进行病毒扫描查杀
    CentOS7上安装MySQL 5.7.32(超详细)
    Centos7.5 安装elasticsearch 7.13.2 遇到的问题记录
  • 原文地址:https://www.cnblogs.com/-zzc/p/12968625.html
Copyright © 2011-2022 走看看