C#反射Refilection

泛型:读取DLL文件描述信息的一个类库

exe/dll(主要区别就是exe文件入口)–metadata(元数据:描述exe/dll文件的一个数据清单)–反射(Reflection)用来操作获取元数据(metadata)
在这里插入图片描述

【1】更新程序时(更新自己的DLL)
【2】使用别人的DLL文件(这种可以读取别人的私有的类型东西)

1. 反射时什么?它就是一个操作metadata数据的一个类库(可以把反射当成一个小工具,用来读取或者操作元数据的)类,方法,特性,属性字段。(为什么要通过反射间接的去操作,1–因为我们需要动态2–读取私有的对象)
2. 使用场合?哪些地方使用到了:asp.net MVC–ORM–IOC–AOP 几乎所有的框架都会使用反射

反射—反射工具—操作metadate【dll中的】(元数据)的工具

通过反射加载DLL文件,相当于把路径找出来
代码示例

using Reflection.DB.Interface;
using Reflection.DB.SQLServer;
using System;
using System.Reflection;

namespace MyReflection
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                #region
                Console.WriteLine("-------------------------------Reflection-------------------------------");
                Console.WriteLine("----加载方式一:dll文件名【需要引用dll】-----");
                Assembly assembly = Assembly.Load("Reflection.DB.SQLServer");//加载方式一:dll文件名
                foreach (var type in assembly.GetTypes())
                {
                    Console.WriteLine("类名{0}:", type.Name);
                    foreach (var method in type.GetMethods())
                    {
                        Console.WriteLine("方法名{0}:", method.Name);
                    }
                }
                Console.WriteLine("----加载方式二:完整路径【不需要引用dll】-----");
                Assembly assembly2 = Assembly.LoadFile(@"F:\01博客代码\02MyReflection\MyReflection\Reflection.DB.Interface\bin\Debug\Reflection.DB.Interface.dll");
                foreach (var type in assembly2.GetTypes())
                {
                    Console.WriteLine("类{0}:", type.Name);
                    foreach (var method2 in type.GetMethods())
                    {
                        Console.WriteLine("方法{0}:", method2.Name);
                    }
                }
                Console.WriteLine("----加载方式三:完全限定名【需要引用dll】-----");
                Assembly assembly3 = Assembly.LoadFrom("Reflection.DB.MySql.dll");
                foreach (var type3 in assembly3.GetTypes())//找到所有类型
                {
                    Console.WriteLine("类{0}:", type3.Name);
                    foreach (var method3 in type3.GetMethods())//找到类型下的所有方法
                    {
                        Console.WriteLine("方法{0}:", method3.Name);
                    }
                }
                #endregion


                #region 使用反射创建对象  反射工具  进行操作DLL的
                Console.WriteLine("-------------------------------使用反射创建对象-------------------------------");
                Assembly assembly4 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
                Type type1 = assembly4.GetType("Reflection.DB.SQLServer.SQLServerHelper");//【2】获取类型(要完整类型名称)
                object oDbHelper = Activator.CreateInstance(type1);//创建对象【创建了对象,在此处,进行调用SQLServerHelper类中的构造函数】
                IDBHelper dBHelper = oDbHelper as IDBHelper;//类型转换 (as转换不报错,类型不对就返回null)
                //IDBHelper dBHelper2 = (IDBHelper)oDbHelper;//转换不成功就会报错,不建议使用这种方式
                dBHelper.Query();
                #endregion

                #region 反射创建对象(带参数的构造函数)
                Console.WriteLine("----------cotr&Parameter---------------");
                Assembly assembly5 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
                Type type2 = assembly5.GetType("Reflection.DB.SQLServer.ReflectionTest");//【2】获取类型(要完整类型名称)
                //获取到这个类型下面所有构造方法
                foreach (ConstructorInfo ctor in type2.GetConstructors())//获取到所有的构造 方法
                {
                    Console.WriteLine(ctor.Name);
                    foreach (var parameter in ctor.GetParameters())//获取到构造方法的所有参数类型
                    {
                        Console.WriteLine(parameter.ParameterType);//显示类型名称
                    }
                }
                Console.WriteLine("----------创建对象---------------");
                object oCotr = Activator.CreateInstance(type2);//无参构造函数
                object oCotr1 = Activator.CreateInstance(type2, new object[] { "编程" });
                object oCotr2 = Activator.CreateInstance(type2, new object[] { 123 });//进行自动匹配
                //相当于下面的写法
                ReflectionTest reflectionTest = new ReflectionTest("测试编程");
                #endregion
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            #region 使用反射创建对象  (私有构造函数)
            //这个功能  还用在我们的单例模式里面(一个对象只能创建一次),这个也叫反射破坏单例
            Console.WriteLine("----------ctor&&Private---------------");
            Assembly assembly6 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
            Type type4 = assembly6.GetType("Reflection.DB.SQLServer.PrivateCtor");//【2】获取类型(要完整类型名称)
            object oPrivate = Activator.CreateInstance(type4, true);
            #endregion

            #region 使用反射创建泛型类
            Console.WriteLine("----------Generic&&Class---------------");
            Assembly assembly7 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//反射的作用就是用来读取DLL
            Type type5 = assembly7.GetType("Reflection.DB.SQLServer.GenericClass`3");//【2】获取类型(要完整类型名称)
            Type makeType = type5.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(double) });
            object oGeneric = Activator.CreateInstance(makeType);
            #endregion


            #region 通过反射调用方法
            Console.WriteLine("----------Method&&&Refection---------------");
            Assembly assembly8 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
            Type type6 = assembly8.GetType("Reflection.DB.SQLServer.ReflectionTest");//【2】获取类型(要完整类型名称)
            object oReflection = Activator.CreateInstance(type6);//创建对象【创建了对象,在此处,进行调用SQLServerHelper类中的构造函数】
            foreach (var method in type6.GetMethods())//所有的方法类型
            {
                Console.WriteLine(method.Name);
                foreach (var parameter in method.GetParameters())
                {
                    Console.WriteLine(parameter.Name + "是:" + parameter.ParameterType);
                }
            }
            //无参数方法调用
            {
                MethodInfo methodInfo = type6.GetMethod("Test1", new Type[] { });
                methodInfo.Invoke(oReflection, null);//调用方法
            }
            //有参数的方法调用
            {
                MethodInfo methodInfo = type6.GetMethod("Test3", new Type[] { typeof(int), typeof(string) });
                methodInfo.Invoke(oReflection, new object[] { 123456, "测试" });//调用方法
            }
            //静态方法的调用
            {
                MethodInfo methodInfo = type6.GetMethod("Test2");
                methodInfo.Invoke(oReflection, null);//调用方法
            }
            #endregion

            #region MyRegion

            //在显示之前做一点其他事情AOP
            Console.WriteLine("----------反射MVC和AOP---------------");
            //在显示之后做一点事情AOP

            //DLl文件名称+类型名称+方法名称(就可以拿到我们的方法)
            //https://localhost:44352/Home/Index  //主机名称,控制器,类型   路由  其本质是反色
            //反射 在MVC中  一些缺点
            //AOP 什么是AOP 是面向切面编程  是OOP对象技术的一种补充
            #endregion

            #region 通过反射调用私有方法
            Console.WriteLine("-----------------private&Reflection-------------------");
            Assembly assembly9 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
            Type type7 = assembly9.GetType("Reflection.DB.SQLServer.ReflectionTest");//【2】获取类型(要完整类型名称)
            object oReflection1 = Activator.CreateInstance(type7);//创建对象【创建了对象,在此处,进行调用SQLServerHelper类中的构造函数】
            MethodInfo methodInfo1 = type7.GetMethod("Test4", BindingFlags.Instance | BindingFlags.NonPublic);
            methodInfo1.Invoke(oReflection1, new object[] { "编程测试" });
            #endregion


            #region 通过反射调用泛型方法[普通类方法中的调用]
            Console.WriteLine("-----------------GenericMethod-------------------");
            Assembly assembly10 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
            Type type8 = assembly10.GetType("Reflection.DB.SQLServer.GenericMethod");//【2】获取类型(要完整类型名称)
            object oReflection2 = Activator.CreateInstance(type8);//实例化类型
            MethodInfo methodInfo2 = type8.GetMethod("Test");//找到调用的方法
            var methodGeneric = methodInfo2.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定参数与参数类型
            methodGeneric.Invoke(oReflection2, new object[] { 1, "编程", DateTime.Now });
            #endregion

            #region 通过反射调用泛型方法[泛型类中,泛型方法的调用]
            Console.WriteLine("-----------------GenericMethod-------------------");
            Assembly assembly11 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
            Type type9 = assembly11.GetType("Reflection.DB.SQLServer.GenericClass`3");//【2】获取类型(要完整类型名称)【`3】表示桑额参数
            Type typeNew = type9.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) }); //确定泛型方法的参数类型
            object oReflection3 = Activator.CreateInstance(typeNew);//实例化类型
            MethodInfo methodInfo3 = typeNew.GetMethod("Test");//找到调用的方法
            MethodInfo methodInfoNew3 = methodInfo3.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定参数与参数类型
            methodInfoNew3.Invoke(oReflection3, new object[] { 1, "编程", DateTime.Now });


            Console.WriteLine("-----------------链式编程GenericMethod-------------------");
            Assembly assembly12 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//【1】加载DLL文件
            Type type10 = assembly12.GetType("Reflection.DB.SQLServer.GenericClass`3").MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
            //Type typeNew1 = type10.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
            object oReflection4 = Activator.CreateInstance(typeNew);
            MethodInfo methodInfo4 = type10.GetMethod("Test").MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });
            //MethodInfo methodInfoNew4 = methodInfo4.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });//确定参数与参数类型
            methodInfo4.Invoke(oReflection4, new object[] { 2, "链式编程", DateTime.Now });
            #endregion

            Console.WriteLine("-----------------通过反射操作字段和属性等成员-----------");
            Student student = new Student()
            {
                id = 1,
                StudentName = "ceshi名称",
                StudentAddress = "ceshi地址"
            };
            Assembly assembly00 = Assembly.LoadFrom("Reflection.DB.SQLServer.dll");//获取dll信息
            Type type00 = assembly00.GetType("Reflection.DB.SQLServer.Student");//找到需要操作的对象类型
            object oStudent = Activator.CreateInstance(type00);//创建对象

            foreach (var prop in type00.GetProperties())
            {
                Console.WriteLine($"{prop.PropertyType}+{prop.Name}={prop.GetValue(student)}");
                Console.WriteLine("----------------------------------------------");
                if (prop.Name.Equals("id"))
                {
                    prop.SetValue(student, 2);
                }
                if (prop.Name.Equals("StudentName"))
                {
                    prop.SetValue(student, "北京");
                }
                if (prop.Name.Equals("StudentAddress"))
                {
                    prop.SetValue(student, "中国北京");
                }
                Console.WriteLine($"{prop.PropertyType}+{prop.Name}={prop.GetValue(student)}");
            }
            //方式二
            //MethodInfo info 成员信息包含-字段  属性  方法
            PropertyInfo[] propertyInfos = type00.GetProperties();//查找所有的属性
            PropertyInfo propertyInfo = type00.GetProperty("id");

            Console.ReadKey();
        }
    }
}


在这里插入图片描述

在这里插入图片描述
demo案例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值