什么是反射与反射的应用及调用方法

  • 前言
  • 为什么学习反射
  • 1.反射创建对象
  • 2.反射调用方法
  • 3.反射调用带参数构造方法
  • 4.反射调用方法
  • 5.反射调用泛型类+泛型方法
  • 6.反射的性能问题
  • 7.反射在框架中的应用
  • 8.封装ORM数据库访问

前言

1.ILspy:逆向工程:可以把Dll/Exe文件反编译回来;
2.IL:是对标于C#代码的代码,不太好阅读
3.metadata:是一个清单数据,只是记录有什么,而不是展示所有的实现;明细账本
4.反射是System.Reflection命名空间,可以读取metadata,并使用metadata;是微软提供的一个帮助类库;
5.下图举例使用ILSpy打开我写的一个实体类。如果使用IL方式呢,我们看到的程序不是很明朗。

6.如果使用C#查看,就可以得到我原本写的代码了。

为什么学习反射

答:因为反射真的是无处不在,ORM/MVC/IOC;

  1. 在MVC编程中比如 “Home/Index” 这样的路径来访问程序文件中的特定类。其实用到的就是反射。
  2. 可以利用反射来生成实体类对象。
  3. 可以利用反射来根据实体类生成自动的查询语句与返回对象。
  4. 反射可以实现程序的解耦(不需要添加项目引用即可使用类)。
  5. 反射可以实现动态配置来实现程序的高可用。

1.反射创建对象

1.目前的结构如上图。调用的方法如下图与代码。

2.加载dll动态库有很多种方式,推荐使用这种方式Assembly.LoadFrom原因:

  • 不需要添加对dll的引用,只需要把dll拷贝到发布目录下即可使用。
  • 不需要全路径,只需要写上DLl的名称即可。PS:后缀要加上 .dll
public static IDBHelper getClass(){//获取数据清单metadataAssembly assembly3 = Assembly.LoadFrom(@"HomeWork.SqlHelper.dll"); //dll名称(需要后缀) ///2.获取类型Type type = assembly3.GetType("HomeWork.SqlHelper.SqlServerHelper");//创建实例object obj = Activator.CreateInstance(type);//类型转换。return obj as IDBHelper;}

2.反射调用方法

通过在上边的简单工厂后,我们实例出来一个接口对象IDBHelper。
接下来就可以通过接口点方法进行使用。

         Console.WriteLine("获取反射类开始!");IDBHelper iDBHelper = SimpleFactory.getClass();5.调用方法Company company = iDBHelper.Find(1);Console.WriteLine("获取反射类完成!");

3.反射调用带参数构造方法

{ Console.WriteLine("*********************Reflection创建带构造函数参数的对象*************************");Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  Type type = assembly3.GetType("HomeWork.SqlHelper.SqlServerHelper");object obj = Activator.CreateInstance(type);object obj1 = Activator.CreateInstance(type, new object[] { "你好" });object obj2 = Activator.CreateInstance(type, new object[] { 123 });object obj3 = Activator.CreateInstance(type, new object[] { 123, "你好" });Type type1 = typeof(SqlServerHelper);}

4.反射调用方法

{//Type type1 = typeof(ReflectionTest);//普通调用方式ReflectionTest reflectionTest = new ReflectionTest();reflectionTest.Show1();reflectionTest.Show2(123);reflectionTest.Show3(123);//reflectionTest.Show4ReflectionTest.Show5("Richard");//Console.WriteLine("*********************Reflection调用普通方法*************************");Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  Type type = assembly3.GetType("HomeWork.SqlHelper.ReflectionTest");object objTet = Activator.CreateInstance(type);//objTet.Show();MethodInfo Show1 = type.GetMethod("Show1");object oResutl1 = Show1.Invoke(objTet, new object[] { });object oResutl = Show1.Invoke(objTet, new object[0]);MethodInfo Show2 = type.GetMethod("Show2");object oResutl2 = Show2.Invoke(objTet, new object[] { 123 });//Console.WriteLine("*********************Reflection调用普重载方法*************************");MethodInfo Show33 = type.GetMethod("Show3",new Type[] { typeof(DateTime)});object oResutl33 = Show33.Invoke(objTet, new object[] { DateTime.Now });Console.WriteLine($"{ typeof(DateTime) }>>>>>oResutl33执行完的参数值{oResutl33}");MethodInfo Show3 = type.GetMethod("Show3", new Type[] { typeof(int), typeof(string) });object oResutl3 = Show3.Invoke(objTet, new object[] { 123, "阳光下的微笑" });MethodInfo Show3_1 = type.GetMethod("Show3", new Type[] { typeof(string), typeof(int) });object oResutl3_1 = Show3_1.Invoke(objTet, new object[] { "明日梦", 234 });MethodInfo Show3_2 = type.GetMethod("Show3", new Type[] { typeof(int) });object oResutl3_2 = Show3_2.Invoke(objTet, new object[] { 345 });MethodInfo Show3_3 = type.GetMethod("Show3", new Type[] { typeof(string) });object oResutl3_3 = Show3_3.Invoke(objTet, new object[] { "赤" });MethodInfo Show3_4 = type.GetMethod("Show3", new Type[0]);object oResutl3_4 = Show3_4.Invoke(objTet, new object[] { });Console.WriteLine("*********************Reflection调用私有方法*************************");MethodInfo Show4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance);object oResutl4 = Show4.Invoke(objTet, new object[] { "伟文" });MethodInfo Show5 = type.GetMethod("Show5", BindingFlags.Static | BindingFlags.Public);object oResutl5 = Show5.Invoke(objTet, new object[] { "追逐梦想的人。。" });object oResutl5_1 = Show5.Invoke(null, new object[] { "you。。" });}

5.反射调用泛型类+泛型方法

Console.WriteLine("*********************Reflections实例化泛型类+调用泛型方法*************************");
{GenericMethod genericMethod = new GenericMethod();genericMethod.Show<int, string, DateTime>(123, "黄大仙", DateTime.Now);Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  Type type = assembly3.GetType("HomeWork.SqlHelper.GenericMethod");object genericTest = Activator.CreateInstance(type);MethodInfo show = type.GetMethod("Show");//注意:需要指定泛型方法的泛型类型MethodInfo show1 = show.MakeGenericMethod(new Type[] { typeof(int), typeof(string), typeof(DateTime) });show1.Invoke(genericTest, new object[] { 123, "黄大仙", DateTime.Now });//如果是泛型方法,需要先确定类型,再执行方法,注意:指定的类型和传入的参数类型必须匹配
}
//泛型类
{Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)  Console.WriteLine(typeof(GenericClass<,,>));//下面的方法未能成功获取到原因由于它是泛型类。要在声明类的时候就告知参数类型//Type type = assembly3.GetType("HomeWork.SqlHelper.GenericClass`3");                    //MethodInfo show = type.GetMethod("Show");//MethodInfo show2 = show.MakeGenericMethod(new Type[] { typeof(DateTime), typeof(int), typeof(string) });Type type = assembly3.GetType("HomeWork.SqlHelper.GenericClass`3");Type type1 = type.MakeGenericType(new Type[] { typeof(int), typeof(string), typeof(DateTime) });object genericObj = Activator.CreateInstance(type1);MethodInfo show1 = type1.GetMethod("Show");show1.Invoke(genericObj, new object[] { 234, "工程师 冯", DateTime.Now });//GenericClass genericClass = new DB.SqlServer.GenericClass();GenericClass<int, string, DateTime> genericClass = new GenericClass<int, string, DateTime>();genericClass.Show(234, "工程师 冯", DateTime.Now);
}

6.反射的性能问题

  • 大家可以通过Stopwatch来监视下获取动态库再到被实例过程需要的时间。可以通过循环来测试。
  • 经测试确实发现反射会带来性能问题。但是仅在获取动态库与创建对象时耗时比较大。
  • 但是是在循环很多次的情况。这种可以通过代码优化来避免。比如。根本不会在循环里获取那么多次对象。把获取对象放在循环外就可以了。
  • 这样速度差异就可以忽略不计了。
    老师讲的一些好处
    //解耦:去掉对细节的依赖
    //如果你们的公司来了一个新的技术经理;说要搞MySql
    //反射来做,
    // 1.仅仅只需要实现MySqlHelper,
    // 2.Copy Dll文件
    // 3.修改配置文件
    //把数据库的版本给更换了
    //实现了程序的可配置;程序的课扩展;
    //反射破坏单例
    //反射可以突破方法的权限限制;

7.反射在框架中的应用

反射:IOC
反射应用于哪些框架;
IOC框架;反射+配置文件+工厂==IOC框架中应用;
反射--MVC
dll: HomeWork.SqlHelper.dll
type: HomeWork.SqlHelper.GenericDouble
就可以创建对象
type可以获取到Method===Method名称--字符串dll名称+类名称+方法名称===可以调用这个方法 localhost://Home/Index/123== 可以调用到MVC项目中的某一个Action,你们觉得这是用的什么技术?
MVC中调用方法就是反射的真实写照。。反射在ORM中的应用:
ORM---对象关系映射,就是通过对类的达成对数据库的操作;
方法、属性、字段

8.封装ORM数据库访问

//控制台程序
{SqlServerHelper sqlServerHelper = new SqlServerHelper();//Company company = sqlServerHelper.QueryCompany(1); Company company = sqlServerHelper.Find<Company>(1);User user = sqlServerHelper.Find<User>(1);Console.WriteLine(company);Console.WriteLine(user);
}//SqlServerHelper中的方法,通过反射结合泛型就能实现数据的查询。经过小扩展可以实现删除与添加数据。
public T Find<T>(int id) where T : BaseModel{string constr = "server=.;database=CustomerDB;uid=sa;pwd=sasa";Type type = typeof(T);object oResult = Activator.CreateInstance(type);var propList = type.GetProperties().Select(p => $"[{p.Name}]");string props = string.Join(",", propList);string sql = $"select {props} from  [{type.Name}] where id={id}";using (SqlConnection con = new SqlConnection(constr)) {using (SqlCommand command=new SqlCommand()){command.Connection = con;command.CommandText = sql;con.Open();SqlDataReader reader = command.ExecuteReader();if (reader.Read()){foreach (PropertyInfo prop in type.GetProperties()){prop.SetValue(oResult, reader[prop.Name]);}}}}return oResult as T;}

2:什么是反射与反射的应用及调用方法(by-朝夕)相关推荐

  1. JAVA 反射 动态获取类,并调用方法

    Class<?> clazz = Class.forName("cn.walle.sysGrid.MyMethod");Object show = (Object) c ...

  2. 【反射机制】Java中的反射机制,使用反射机制创建对象、访问属性、方法、构造方法等

    这篇文章主要是整理了Java中的反射机制,包括:反射机制概念.反射机制访问构造方法.反射机制访问普通方法.反射机制访问属性,反射机制访问修饰符. 目录 一.反射机制概念 二.反射机制使用 (1)加载C ...

  3. Golang反射机制的实现分析——reflect.Type方法查找和调用

    在<Golang反射机制的实现分析--reflect.Type类型名称>一文中,我们分析了Golang获取类型基本信息的流程.本文将基于上述知识和经验,分析方法的查找和调用.(转载请指明出 ...

  4. 通过反射获取及调用方法(Method)

    1.获取方法 使用反射获取某一个类中的方法,步骤: ①找到获取方法所在类的字节码对象 ②找到需要被获取的方法 Class类中常用方法: public Method[] getMethods():获取包 ...

  5. Java中为什么需要反射?反射要解决什么问题?

    Java中为什么需要反射?反射要解决什么问题? 参考文章: (1)Java中为什么需要反射?反射要解决什么问题? (2)https://www.cnblogs.com/buoge/p/9285142. ...

  6. C#的反射机制调用方法

    .NET的反射(Reflection)是非常完善和强大的,例如有名的.NET反编译工具Red Gate's .NET Reflector就是使用了.NET自身的反射机制,这里有一个比较简单的实例(使用 ...

  7. 【EventBus】事件通信框架 ( 订阅方法注册 | 检查订阅方法缓存 | 反射获取订阅类中的订阅方法 )

    文章目录 一.检查订阅方法缓存 二.反射获取订阅类中的订阅方法 三.完整代码示例 一.检查订阅方法缓存 注册订阅者时 , 只传入一个订阅者类对象 , 其它信息都需要通过反射获取 ; 1. 获取订阅者类 ...

  8. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取要注入事件的 View 对象 | 通过反射获取 View 组件的事件设置方法 )

    文章目录 前言 一.获取要注入事件的 View 对象 二.通过反射获取 View 组件的事件设置方法并执行 前言 Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , ...

  9. java 反射 ppt_Java反射的基本使用

    这里是修真院后端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析后端知识/技能,本篇分享的是: [Java反射的 ...

  10. java反射的优化_请问Java反射的性能为什么比直接调用慢一个数量级左右?

    Method.invoke()本身要用数组包装参数:而且每次调用都必须检查方法的可见性(在Method.invoke()里),也必须检查每个实际参数与形式参数的类型匹配性(在NativeMethodA ...

最新文章

  1. R可视化绘制对数正态分布(Log Normal Distribution)
  2. SQL Server 2012笔记分享-49:理解数据库快照
  3. 添加元素的注意问题 复习 介绍 元素的创建 元素添加的方法 元素移除的方法
  4. Spring--@within和@target的区别
  5. 非常有用的并发控制-倒计时器CountDownLatc
  6. 或许是单选的飞鸽传书
  7. 取消hibernate的外键生成
  8. linux:tr的用法
  9. 嵌入式Linux入门4:版本控制git的使用
  10. 网站建设对于哪些刚起步的企业是有必要的
  11. PHPKafka 1.0 发布,支持全部 50 个 API
  12. Atitit 数据控制语言与权限  DCL
  13. RNA_seq(1)植物转录组实战(上)之salmon进行索引建立和转录组定量
  14. 宠物领养平台的分析与实现
  15. Quartz——CronTrigger触发器
  16. 【项目实践】网络对战五子棋
  17. 基于SpringBoot的框架SOFABoot,青出于蓝而胜于蓝
  18. MathType 公式编辑器公式大小调整
  19. android 正三角,倒三角的实现代码
  20. 在Windows10操作系统中任务栏的网络图标消失不见了该怎么办呢

热门文章

  1. connect ETIMEDOUT......
  2. 中值滤波(资料整理,持续更新)
  3. 数据结构 严薇敏 队列 的实现及其使用方法详解
  4. 《数据结构(C语言版)》严巍敏课件~第二章:线性表
  5. 第五章——大数定律和中心极限定理
  6. 个人隐私的泄露在日常工作、生活、学习中,每个人都要学会保护自己的个人隐私
  7. HMMer在Windows环境下的安装
  8. 企业家普遍关注的问题是什么?
  9. Python实现去除图片中的数字水印
  10. 列出MSSQL所有数据库名、所有表名、所有字段名