原文链接:农码一生

反射是:指程序可以访问、检测和修改它本身状态或行为的一种能力。
反射是一种能力,所以给的定义就是说明了它能干嘛
我们平时用反射主要做:

1、获取类型的相关信息
2、动态调用方法
3、动态构造对象
4、从程序集中获得类型

1、获取类型的相关信息

反射的核心Type类,Type对象提供的属性和方法可以获取对象的一切信息。如:方法、字段、属性、事件……等。

我们获取已加载程序集中类型的Type对象的几种方法:(以StringBuilder类型为例)

1、直接使用typeof操作符 Type t1 = typeof(StringBuilder);
2、通过类型实例Type t2 = new StringBuilder().GetType();
3、通过Type类的静态方法Type t3 = Type.GetType("System.IO.Stream");

不管使用那种,我们最终得到的结果都是一样的。那么我们通过Type又能得到些什么信息呢?

Type T1 = typeof(StringBuilder);
Console.WriteLine("命名空间名称:" + T1.Namespace);
Console.WriteLine("直接基类型:" + T1.BaseType);
Console.WriteLine("全名:" + T1.FullName);
Console.WriteLine("是抽象类型:" + T1.IsAbstract);
Console.WriteLine("是类:" + T1.IsClass);

2、动态调用方法

public class TClass
{public void fun(string str){Console.WriteLine("我是fun方法,我被调用了。" + str);}public void fun2(){Console.WriteLine("我是fun2方法,我被调用了。");}public static void fun3(){Console.WriteLine("我是fun3静态方法,我被调用了");}
}

调用方式一(使用InvokeMember调用方法)

//1、调用带参实例方法fun
Type T1 = typeof(TClass);
T1.InvokeMember("fun", BindingFlags.InvokeMethod, null, new TClass(), new string[] { "test" });//2、调用无参实例方法fun2
Type T1 = typeof(TClass);
T1.InvokeMember("fun2", BindingFlags.InvokeMethod, null, new TClass(), null);//3、调用静态方法
Type T1 = typeof(TClass);
T1.InvokeMember("fun3", BindingFlags.InvokeMethod, null, T1, null);

调用方式二(使用MethodInfo.Invoke调用方法)

Type T1 = typeof(TClass);
T1.GetMethod("fun", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), new string[] { "testfun1" });
T1.GetMethod("fun2", BindingFlags.Instance | BindingFlags.Public).Invoke(new TClass(), null);
T1.GetMethod("fun3", BindingFlags.Static | BindingFlags.Public).Invoke(T1, null);

真正的全动态调用
上面的两种方式,在编写代码的时候总是要先确定了已知的对象名和方法名。那么我们在不知道对象和方法名的时候是否也可以调用呢?答案是肯定的,实现如下:

Console.WriteLine("请输入对象类名");
string className = Console.ReadLine();
Console.WriteLine("请输入要执行的方法名");string funName = Console.ReadLine();
Type T1 = Type.GetType(className);ConstructorInfo ci = T1.GetConstructors()[0]; //获取构造函数
var obj = ci.Invoke(null);//实例化构造函数T1.InvokeMember(funName, BindingFlags.InvokeMethod, null, obj, null);

3、动态构造对象

public class TClass
{public TClass(){Console.WriteLine("构造函数被执行了。。");}public TClass(string str){Console.WriteLine("有参构造函数被执行了。。" + str);}
}

动态构造对象

/动态构造对象,方式一
Assembly asm = Assembly.GetExecutingAssembly();
TClass obj = (TClass)asm.CreateInstance("net.tclass", true);//true:不区分大小写//动态构造对象,方式二
ObjectHandle handler = Activator.CreateInstance(null, " net.TClass");//null:当前程序集
obj = (TClass)handler.Unwrap();//动态构造对象,方式三(构造有参构造函数)
Assembly asm2 = Assembly.GetExecutingAssembly();
obj = (TClass)asm2.CreateInstance("net.tclass", true, BindingFlags.Default, null, new string[] { "test" }, null, null);//true:不区分大小写   

获取和修改属性:

var obj = new TClass();
obj.name = "张三";
Type type = typeof(TClass);
//获取属性
var Name = type.InvokeMember("name", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null,obj, new object[] { }) as string;
Console.WriteLine(obj.name);
//设置属性
type.InvokeMember("name", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null,obj, new object[] { "新属性(李四)" });
Console.WriteLine(obj.name);

从程序集中获得类型
取得当前代码所在程序集(使用GetExecutingAssembly)

Assembly ass = Assembly.GetExecutingAssembly();
Console.WriteLine("当前所在程序集名:"+ass.ManifestModule.Name);
Console.WriteLine("当前所在程序集路径:"+ass.Location);

通过反射加载程序集并创建程序中的类型对象
从程序集中获得类型,这个应该是我们平时用得比较多。如我们所谓的依赖注入和控制反转(这个主题将在下篇博文进行分析)就用到了通过反射从程序集中获取类型。

首先我们还是看看怎么从程序集中获得类型吧。我们可以使用Assembly类型提供的静态方法LoadFrom()或Load(),如:

Assembly asm = Assembly.LoadFrom("Demo.dll");
Assembly asm = Assembly.Load("Demo");

区别:

Assembly asm = Assembly.LoadFrom("net.exe");//需要加后缀,可以指定路径,如下面的
Assembly asm1 = Assembly.LoadFrom(@"C:\01文件\05Svn\BlogsCode\Blogs\Blogs.Web\bin\Blogs.BLL.dll");Assembly asm2 = Assembly.Load("Blogs.BLL");//无需加后缀,不可以指定路径
//Assembly asm3 = Assembly.Load(@"C:\01文件\05Svn\BlogsCode\Blogs\Blogs.Web\bin\Blogs.BLL");//这里会报错
//使用Load可以加载当前程序bin目录行下的程序集或者系统程序集//这里TClass可以是一个接口,那么可以在外面的dll任意实现了。
TClass obj = (TClass)asm2.CreateInstance("net.tclass", true);//true:不区分大小写
obj.fun();//***调用动态加载的dll中的方法***

在讲依赖注入的时候会讲到,同学们继续关注哦~)

从上所知,反射不是某一个概念,而是一类操作的统称。或者说是某些能力的统称。 感觉不好回答反射到底是什么,只能说反射能干什么。它能动态创建对象、动态调用对象方法、动态读取和设置属性和字段、它能动态加载程序外的dll。总的感觉就是大多数都是跟“动态”扯上了关系。

学习本是一个不断抄袭、模仿、练习、创新的过程。
虽然,园中已有本人无法超越的同主题博文,为什么还是要写。
对于自己,博文只是总结。在总结的过程发现问题,解决问题。
对于他人,在此过程如果还能附带帮助他人,那就再好不过了。

什么是反射,反射能干嘛?相关推荐

  1. java反射详解---具体代码操作看看反射都能干些什么

    1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  2. Proxy代理 和 Reflect反射(反射的是obj)的概念

    1. Proxy代理 // 供应商(原始对象)let obj = {time:'2018-01-03',name:'net',_r: "123"}// 创建代理商,传入obj数据l ...

  3. Unity C#基础之 反射反射,程序员的快乐

    反射反射,程序员的快乐 这句话想必大家都经常听过,基本上在绝大多数的框架和一些设计模式中都能看到反射的身影(MVC.IOC.AOP.O/RM), 反射:是.Net Framework提供的一个帮助类库 ...

  4. java 反射.问题_Java知识点总结(反射-反射机制性能问题)

    Java知识点总结(反射-反射机制性能问题) @(Java知识点总结)[Java, 反射] 性能相关注意点: setAccessible 启用和禁用访问安全检查的开关,值为 true 则指示反射的对象 ...

  5. 黑马程序员-反射-constructor-feld类-Method-数组的反射-反射的作用

    ---------------------- android培训.java培训.期待与您交流! ---------------------- 反射的基石→Class类 Java程序中的各个Java类属 ...

  6. Java反射——反射机制问题——第一章

    Java反射--反射机制问题--第一章 Java反射--Class类--第二章 Java反射--类加载--第三章 Java反射--反射获取类的结构信息--第四章 文章目录 1:一个需求引出反射 2:反 ...

  7. 抽象工厂+反射=反射工厂

    在我的上一篇文章(疑惑?改良?从简单工厂到工厂方法)中,详细论述了创建模式中简单工厂到工厂方法的演变过程,并试图结合工厂方法的设计以及.net中的反射机制之所长,改良出一种新型的工厂-反射工厂,这当然 ...

  8. 你必须了解的反射——反射来实现实体验证

    开发工作中,都会需要针对传入的参数进行验证,特别是针对实体进行验证,确保传入的参数格式正确.这里做了一个非常简单的组件进行验证.抛砖引玉,让大家深入思考下反射的应用. 需求 日常开发,都是通过API进 ...

  9. 方法的反射---反射学习笔记(二)

    方法的反射:其实就是通过方法的对象来调用方法. 如何获取某个方法:方法的名称和方法的参数列表才能唯一决定某个方法 方法反射如何操作呢? 1.要获取一个方法(就是获取类的信息),要获取类的信息首先要获取 ...

  10. 什么是反射 反射怎么用

    Java中有许多对象在运行时都会出现两种类型:编译时类型和运行时类型.例如下面的语句: Parent p = new Child(); 变量p在编译时的类型为Parent,运行时类型为Child,体现 ...

最新文章

  1. elk6.3.1版本+metricbeat监控收集swarm的资源使用情况
  2. Linux日志 系统日志及分析
  3. jQuery 遍历
  4. 《大数据》第1期“专题”——大数据机器学习系统研究进展(上)
  5. c 与matlab混编,C与MATLAB混合编程之调用MATLAB引擎
  6. 51单片机点亮数码管
  7. python并集符号_Python Union()用法及代码示例
  8. win10怎么设置默认浏览器_如何将浏览器设置为默认浏览器?最简单的方法
  9. java中 有return 的情况,return以及try,finally代码块的执行顺序
  10. 解决libc.so.6: version `GLIBC_2.14#39; not found问题
  11. [书籍翻译]12周撰写期刊文章 学术出版成功指南——第 4 周:选择期刊
  12. 【STM32F407的DSP教程】第13章 DSP快速计算函数-三角函数和平方根
  13. 三种简单的浏览器设置自动刷新网页
  14. 台式计算机用什么电源线,电脑电源线有什么规格
  15. Dark Crystal RAT的新变种分析
  16. 【技术贴】关于IE主页被篡改、假IE的根治方法。。。
  17. html页面悬浮提示框,js实现页面悬浮框
  18. hdu_1720 A+B Comeing
  19. 国外开放课程及一些国外大学的网址
  20. Image Caption Generation原理简介

热门文章

  1. Win10 64位系统安装Microsoft Visual Studio和Intel Fortran(非正式名称)
  2. linux设置NLS_LANG
  3. 022 PHP获取从周一到周日的时间戳
  4. 指针式仪表识别读数 Python
  5. 支付退款流程设计_如何设计订单系统?不妨看看这篇文章
  6. 8岁 YouTube博主年收入1.8亿,成最赚钱博主!
  7. 关于AP, MAP的一些理解
  8. 品酒论三国之一(创业时代的第二堂必修课:自助者天助)
  9. Discuz!NT 代码阅读笔记(8)--DNT的几个分页存储过程解析
  10. 网易视频云谈视频云的根基:云计算的介绍