《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. UEFI和GPT下硬盘克隆后的BCD引导修复

    UEFI和GPT下硬盘克隆后的BCD引导修复-Storm_Center http://www.stormcn.cn/post/1901.html 当硬盘引导换成GPT,系统启动也变成UEFI后,如果直 ...

  2. 前端-JavaScript1-5——JavaScript之变量的类型

    5.1 概述 基本类型5种 number          数字类型 string             字符串类型 undefined      undefined类型,变量未定义时的值,这个值自 ...

  3. 采用ddt 可以把ddt获取的数据 塞进测试用例里面的备注里面去展示 (还没有试)

  4. ubuntu crontab python 定时任务备记

    crontab -e 写入: # at a.m every week with: # * * tar -zcf /var/backups/home.tgz /home/ # # For more in ...

  5. [UE4]Text Box

    Text Box:文本输入控件. 一.新建一个名为testTextBox的UserWidget,添加一个名为“EditableTextBox_0”的TextBox到默认容器Canvas Panel 二 ...

  6. Zabbix监控进程(进程消失后钉钉报警)

    用于python报警的脚本如下:(钉钉机器人的连接需要修改) #!/usr/bin/python3# -*- coding: utf-8 -*-# Author: aiker@gdedu.ml# My ...

  7. 学习MeteoInfo二次开发教程(八)

    总体没什么问题. 1.创建Projection菜单,Lambert,Geographic,ShowLatLon子菜单. 2.需要添加: using MeteoInfoC.Projections; 3. ...

  8. QQ第三方登录(完结篇)

    书接上回,上回说到:这篇是代码篇 首先我们先来看一下我的母鹿(目录)吧 Connect2.1  是我们从下载的SDK,内容包含 其他文件在配置之后全部删除了! index.html 是我们点击登陆的页 ...

  9. MyISAM与InnoDB两者之间区别与选择,详细总结,性能对比

    1.MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.不 ...

  10. WPF程序 双击exe自动申请“以管理员方式运行”权限

    实现方式: 在 xxx.exe 目录下包含其对应的清单文件(xxx.exe.manifest, 由 VS 编译时自动生成): 用记事本打开 manifest 文件,将文件中的项:<request ...