《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章反射的更多相关文章

  1. SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)

    SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...

  2. Javascript高级程序设计读书笔记(第10章 DOM)

    第10章 DOM 10.1  节点层次 每个节点都有一个nodeType属性,用于表明节点的类型.任何节点类型必是下面中的一个: Node.Element_NODE(1); NODE.ATTRIBUT ...

  3. C++ Primer 读书笔记:第10章 关联容器

    第10章 关联容器 引: map set multimap multiset 1.pair类型 pair<string, int> anon anon.first, anon.second ...

  4. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  5. 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系

    本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...

  6. 《Linux内核设计与实现》读书笔记——第一、 二章

    <Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...

  7. 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程

    第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...

  8. CLR via c#读书笔记八:泛型

    1.定义泛型类型或方法时,为类型指定的任何变量(比如T)都称为类型参数.使用泛型类型或方法时指定的具体数据类型称为类型实参. 2.System.Collections.Concurrent命名空间提供 ...

  9. Machine Learning for hackers读书笔记(八)PCA:构建股票市场指数

    library('ggplot2') prices <- read.csv('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\08-PC ...

随机推荐

  1. <Differential Geometry of Curves and Surfaces>(by Manfredo P. do Carmo) Notes

    <Differential Geometry of Curves and Surfaces> by Manfredo P. do Carmo real line Rinterval I== ...

  2. 廖雪峰Java6 IO编程-3Reader和Writer-1Reader

    1.java.io.Reader和java.io.InputStream的区别 InputStream Reader 字节流,以byte为单位 字符流,以char为单位 读取字节(-1,0-255): ...

  3. java反编译工具cfr

    http://www.benf.org/other/cfr/ 下载反编译工具 @echo off SET home=%cd% rem 指定存放jar包的目录 SET jar_dir=%home%\ja ...

  4. 优化 SQL SELECT 语句性能

    SELECT语句的性能调优有时是一个非常耗时的任务,在我看来它遵循帕累托原则.20%的努力很可能会给你带来80%的性能提升,而为了获得另外20%的性能提升你可能需要花费80%的时间. 检查索引:在SQ ...

  5. gdb 使用

    2018年7月27日21:05:16 —— 多进程调试 1.follow_fork_mode 作用:在fork之后跟随父进程还是子进程 可以使用 show follow_fork_mode查看再for ...

  6. 如何解决python 图表中文显示乱码问题(matlplotlib 包)

    目前搜到的是,下载一个字体到程序路径,设置成默认字体.  https://blog.csdn.net/irene_loong/article/details/68955485 #图表显示中文设置 im ...

  7. powerdesigner 基本概念

    PowerDesigner是Sybase的企业建模和设计解决方案,采用模型驱动方法,将业务与IT结合起来,可帮助部署有效的企业体系架构,并为研发生命周期管理提供强大的分析与设计技术.PowerDesi ...

  8. 析构方法(__del__)

    析构方法,当对象在内存中被释放时(也就是实例执行完了,实例的内存就会自动释放,这时候就会触发),自动触发执行. 当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被 ...

  9. 尚硅谷springboot学习30-docker安装mysql示例

    docker pull mysql 错误的启动示例 错误日志:需要设置密码 正确的启动 但还不能直接使用,因为没有做端口映射,外界无法连接 可用的启动 连接成功 几个高级的操作 指定配置文件 dock ...

  10. [FE] 有效开展一个前端项目1

    今天的前端如果没有用到 npm,效率是比较低的:所以要从使用的工具来讲. 1. 一切都依赖于 nodejs: 下载一个 linux 的源码包就可以开始安装了. $ wget https://nodej ...