反射简单介绍

**

程序集与元数据

**
什么是程序集?程序及是编译器编译得到的,供进一步编译执行的中间产物
在windo系统中,一般表现后缀位.dll(库文件)或者是.exe(可执行程序)
.dll文件是类库工程文件,是纯代码逻辑,不能直接运行
元数据
元数据就是用来描述数据的数据,保存在程序集中。例如,程序中的类,类中的函数、变量等等。

**

反射的概念

程序在运行时,可以查看其他程序集或者自身的元数据,这个过程叫做反射。
通过反射,可以得到程序集中的各种信息。

**

反射的语法

Type类
Type 类的信息 类
反射的基础
访问元数据的主要方式
首先创建一个类用于测试

	class Test
    {
        private int id;
        private string name;
        public int a = 12;

        public Test()
        {

        }
        public Test(int id)
        {
            this.id = id;
        }
        public Test(int id,string name):this(id)//调用上面的重载
        {
            
            this.name = name;
        }

        public void Xinxi()
        {
            Console.WriteLine(id + " " + name);
        }

    }
  1. 获取Type
			//1.object中的GetType()可以获取对象的Type
            int a = 1;
            Type type1 = a.GetType();//把a 属于的 类中的信息 传递给type1

            //2.通过typeof关键字 传入类名 得到Type对象(一般用于同一个程序集)
            Type type2 = typeof(Test);

            //3.通过类名获取
            //注意 类名必须包含命名空间,不然找不到
            //Type type3 = Type.GetType("Int32");没有包含命名空间,找不到
            Type type3 = Type.GetType("System.Int32");
  1. 得到类的程序集信息
			//可以通过Type得到类型所在的程序集信息
            Console.WriteLine(type1.Assembly);
  1. 获取类中的所有 公共 成员
            //需要引入命名空间using System.Reflection
            //MemberInfo 信息类 可以存储所有信息
            MemberInfo[] infos = type2.GetMembers();
            foreach(var item in infos)
            {
                Console.WriteLine(item);
            }
  1. 获取类的所有构造函数并且调用
            //ConstructorInfo类 可以储存构造函数的信息
            ConstructorInfo[] ctorInfo = type2.GetConstructors();
            foreach(var item in ctorInfo)
            {
                Console.WriteLine(item);
            }
  1. 获取其中一个构造函数 并执行
            //得到构造函数传入Type类型的数组,数组中内容按顺序是参数类型

            //1.获取无参构造
            ConstructorInfo info = type2.GetConstructor(new Type[0]);
            Test obj = info.Invoke(null) as Test;

            //2.获取有参构造
            ConstructorInfo info2 = type2.GetConstructor(new Type[] { typeof(int) });
            Test obj2 = info2.Invoke(new object[] { 2 }) as Test;

  1. 获取类的公共成员变量
            //1.得到所有成员变量
            FieldInfo[] fiInfos = type2.GetFields();
            foreach(var item in fiInfos)
            {
                Console.WriteLine(item);
            }
            
            //2.得到指定名称的公共成员变量
            FieldInfo fiInfo1 = type2.GetField("a");
            Console.WriteLine(fiInfo1); 

            //3.通过反射获取和设置对象的值
            Test test1 = new Test();
            test1.a = 5;
            //获取对象某个变量的值
            Console.WriteLine(fiInfo1.GetValue(test1));
            //设置指定对象的某个变量
            fiInfo1.SetValue(test1, 5);
  1. 获得类的公共成员方法
            //通过Type类中的GetMethod方法 得到类中的方法
            //如果方法存在重载,GetMethod(string name,new Type[] {typeof(type)})
            MethodInfo[] meInfos = type2.GetMethods();
            MethodInfo meInfo1 = type2.GetMethod("Xinxi");
            //调用该方法
            Test test2 = new Test(1, "sss");
            meInfo1.Invoke(test2,null);

其中Xinxi方法的代码如下:

	public void Xinxi()
        {
            Console.WriteLine(id + " " + name);
        }

Activator类
用于快速实例化对象
用于将Type对象快捷实例化为对象
先得到Type,让快速实例对象

  1. 有参构造`
			Test testobj2=Activator.CreateInstance(testType, 2,"qqq")as Test;
  1. 无参构造
			Type testType = typeof(Test);
            Test testobj= Activator.CreateInstance(testType) as Test;

Assembly类
程序集类
用来加载程序集,加载后才能用Type来使用其他程序集的信息

加载同一文件夹下的其他程序集
Assembly asemble2=Assembly.Load(“name”);

加载不同文件夹下的程序集
Assembly asemble2=Assembly.LoadFrom(“包含程序集清单的文件的名称或路径”);
Assembly asemble3=Assembly.LoadFile(“要加载文件的完全限定路径”);
使用过程

			Assembly asemble2 = Assembly.LoadFrom(@"E:\c# code\ShuJuJieGou\ListPaiXu\bin\Debug\net5.0\ListPaiXu");
			//注意:"\"代表转义字符,在复制路径时要在前面加上"@"取消转义字符的使用
            
            Type[] atypes = asemble2.GetTypes();
            foreach(var item in atypes)
            {
                Console.WriteLine(item);
            }
            //然后在加载程序集中的一个类对象
            Type st = asemble2.GetType("ListPaiXu.ShopItem");
            //实例对象
            Object spItem= Activator.CreateInstance(st, 2);
上一篇:qt5 qmake开发


下一篇:c – 结合QtConcurrent调用