《C#从现象到本质》读书笔记(八)第10章反射
《C#从现象到本质》读书笔记(八)第10章反射
个人感觉,反射其实就是为了能够在程序运行期间动态的加载一个外部的DLL集合,然后通过某种办法找到这个DLL集合中的某个空间下的某个类的某个成员(通过反射可以访问该类所包含的所有成员,不论成员是公有还是私有)。
在.NET中,查看和操作元数据的动作,称为反射。
通过反射我们可以:1)加载一个程序集,这称为动态加载程序集或者晚期绑定。2)获得程序集的托管模块(IL+元数据)。3)获得程序集中(托管模块中的)类型对象(通过元数据)。4)获得类型的成员和方法,反射可以访问类型所有的成员和方法,无论它们是不是私有的。
System.Type类会返回加载堆上的类型对象(包括静态成员和方法表)。
当我们要反射一个类的方法时,首先要获得它的类型对象,然后再使用GetMethods方法获得某个方法,获得方法之后,可以使用Invoke执行方法。
GetMembers方法默认只获得公开的成员,包括自己和类型所有父类的公开成员。
即使成员是私有的或受保护的,通过反射一样可以获得其值,甚至可以对其值进行修改。
class Program
{
static void Main()
{
var shapeList = new List<Shapes> { new Rectangle(), new Circle() };
var method = typeof(Processor).GetMethod("Process"); foreach (var shapes in shapeList)
{
//对每个shapes,获得它的类型,然后构造相应的泛型方法
var generateRef = method.MakeGenericMethod(shapes.GetType()); //调用方法
generateRef.Invoke(new Processor(), null);
} Console.ReadKey();
}
} class Processor
{
public void Process<T>() where T : Shapes, new()
{
var t = typeof(T);
t.GetMethod("Print").Invoke(new T(), null);
}
} class Shapes
{
public void Print()
{
Console.WriteLine("我是形状");
}
} class Rectangle : Shapes
{
public void Print()
{
Console.WriteLine("我是长方形");
}
} class Circle : Shapes
{
public void Print()
{
Console.WriteLine("我是圆形");
}
}
在很多时候反射是唯一的选择,例如晚期绑定:当需要动态加载某个程序集(而不是在程序开始时就加载),需要使用反射。如果系统需要面对的是通用的模型,此时无论是方法也好属性也罢,都是随应用场景而改变的,这种完全需呀动态绑定的场景下自然需要运用反射。
方法的调用有三种主要形式:直接调用,委托调用和反射调用。委托调用又可以分为直接创建强类型委托和使用表达式辅助创建委托两种方式。
性能比较:直接调用>委托调用>通用委托调用>表达式调用>反射调用>委托的DynamicInvoke调用。
反射在ORM中有着广泛的用途。
书中有一个简单的ORM的实现。代码也很详细。
《C#从现象到本质》读书笔记(八)第10章反射的更多相关文章
- SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)
SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...
- Javascript高级程序设计读书笔记(第10章 DOM)
第10章 DOM 10.1 节点层次 每个节点都有一个nodeType属性,用于表明节点的类型.任何节点类型必是下面中的一个: Node.Element_NODE(1); NODE.ATTRIBUT ...
- C++ Primer 读书笔记:第10章 关联容器
第10章 关联容器 引: map set multimap multiset 1.pair类型 pair<string, int> anon anon.first, anon.second ...
- 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化
第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...
- 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系
本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...
- 《Linux内核设计与实现》读书笔记——第一、 二章
<Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...
- 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程
第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...
- CLR via c#读书笔记八:泛型
1.定义泛型类型或方法时,为类型指定的任何变量(比如T)都称为类型参数.使用泛型类型或方法时指定的具体数据类型称为类型实参. 2.System.Collections.Concurrent命名空间提供 ...
- Machine Learning for hackers读书笔记(八)PCA:构建股票市场指数
library('ggplot2') prices <- read.csv('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\08-PC ...
随机推荐
- Linux查看线程
我的程序在其内部创建并执行了多个线程,我怎样才能在该程序创建线程后监控其中单个线程?我想要看到带有它们名称的单个线程详细情况(如,CPU/内存使用率). 线程是现代操作系统上进行并行执行的一个流行的编 ...
- CSS之边框
<!DOCTYPE html> <!--边框--> <html lang="en"> <head> <meta charset ...
- NIOS II With uCOSII
1.如果使用uCOS,那么Qsys中Nios II核就不能使用外部中断控制器(EIC). 2.遇到很迷惑的问题,运行uCOSII的实例代码,总是在第二个OSTimeDlyHMSM(0, 0, 3, 0 ...
- IDEA查看类继承关系及生成类关系图
1.在想要查看的类上按 Ctrl + H -> Diagrams -> Show Diagrams -> Java Class Diagrams -> Show Impleme ...
- JavaSE中的小知识点分析
1.System.out.println(); 调用System类中的public static final PrintStream out,输出为PrintStream(字节形式的输出流,为Outp ...
- JAVA 注解,泛型,反射获取泛型,并实例化
JAVA 的泛型加大了 编程的灵活性,在配合上反射,可以让我们省去大量的重复代码,当你用 SpringBoot 整合 JPA 的时候 你会发现,你的 DAO 层只需要继承 BaseDao,在显示标明泛 ...
- [java]给出一个字符串,将重复的字符去除,仅保留第一次出现的字符,且保持去重后的字符在原字符串中的顺序不变
- vue 全局组件【原】
1.目录 2.内容 -Loading.vue <template> <div class="loading"> loading... </div> ...
- 29.Hibernate-二级缓存和session管理.md
目录 1.概念 1.1一级缓存: 1.2二级缓存: 2.使用方法 3.策略 3.1缓存策略 3.2集合缓存 3.3查询缓存 5. Seesion管理 1.概念 Hibernate提供的缓存 有一级缓存 ...
- 26.Hibernate-主键和映射.md
目录 1.复合主键映射 [toc] 2.集合映射 2.1Set集合 2.2其他集合 [toc] 3.集合数据的读取 [toc] 4.一对多和多对一映射 4.1概念 4.2配置和开发 4.2.1关键点 ...