C# 反射研究
概念
反射这东西,对于我这种小白,听起来总是觉得好大上的。
当初理解它费了一点时间,后来看了一句话,突然恍然大悟,“反射就跟B超一样,我们在不剖开人体的情况下想看清楚内部情况,
我们就通过发射超声波,然后根据超声波反射回来的情况,描绘出人体内部的细节”。
比喻得很形象呢呵呵,C#的反射也差不多这样,我们想要探究一个类(或程序集)内部的情况,
但我们又没有权限进入内部查看,于是我们用反射,然后获取该程序集内部的情况,达到使用引用他的目的。
这是比较官方化的定义:反射就是审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)
就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。

作用
反射的作用,说白了就是在程序运行时可以动态获取其他程序集(dll)等的内部情况,然后可以动态加载并使用他们。
1、最常见的一个做法,就是插件。.Net程序的插件写法就是:你预留一些接口,然后编写插件的人根据你预留的接口写插件,
并将编译好的dll放到对应文件夹,那么你的程序运行时就会用反射动态加载使用这些插件。
2、还有一个很牛逼的做法就是可以达到修改程序一些行为的目的,例如Unity的Editor,虽然支持编程插件,但一些API并不对外
开放,你可以通过反编译Unity的dll(前提是你反编译得了),然后获取某个功能是用什么API完成的,然后通过反射加载Editor
的dll,并根据上一步获取的API用法,自己来使用这些不公开的API。
参考雨松MONO的博客:http://www.xuanyusong.com/archives/3796
3、另一个用法就是可以通过函数名加载函数拉,比如本人最近在做一个插件(类PlayMaker的可视化FSM插件),里面有个功能类,
这个功能类里有许多的函数,每个函数对应一个功能,然后在程序运行时会将这些函数映射到屏幕上的一个列表里,你点击列表里的
哪个按钮,就执行哪个函数。虽然可以通过为每个函数绑定一个Button实现,但比如函数非常多,这样就忙不过来了,而且达不到可以
动态修改的目的。比如你以后要多添加几个功能函数,那么又要为它们绑定几个按钮。我的想法就是在创建列表的时候扫描这个类,
将这个类的所有函数列出来,然后为他们绑定按钮。反射帮助了我。(大误:刚刚百度了下,才知道通过函数名加载函数没必要用反射,
直接Type.GetMethod就能返回函数数组了,反射性能不高,没必要用)
参考我这篇文章的第六点:http://www.cnblogs.com/jeason1997/p/4802116.html
注:顺便一说,Unity里的SendMessage就是通过反射调用回调函数的,SendMessage("Methon Name");
使用
//获取类型信息
Type type = typeof(MyClass);
Response.Write("类型名:" + type.Name);
Response.Write("类全名:" + type.FullName);
Response.Write("命名空间名:" + type.Namespace);
Response.Write("程序集名:" + type.Assembly);
Response.Write("模块名:" + type.Module);
Response.Write("基类名:" + type.BaseType);
Response.Write("是否类:" + type.IsClass);
Response.Write("类的公共成员:"); //得到所有公共成员
MemberInfo[] memberInfos = type.GetMembers();
foreach (var item in memberInfos)
Response.Write(string.Format("成员类型" + item.MemberType));
//获取当前执行代码的程序集
Assembly assem = Assembly.GetExecutingAssembly(); Response.Write("程序集全名:"+assem.FullName);
Response.Write("程序集的版本:"+assem.GetName().Version);
Response.Write("程序集初始位置:"+assem.CodeBase);
Response.Write("程序集位置:"+assem.Location);
Response.Write("程序集入口:"+assem.EntryPoint); Type[] types = assem.GetTypes();
Response.Write("程序集下包含的类型:");
foreach (var item in types)
{
Response.Write("类:"+item.Name);
}
// 动态加载Dll并反射调用程序集中的方法
protected void Page_Load(object sender, EventArgs e)
{
System.Reflection.Assembly ass = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory+"bin\\Test.dll"); //加载DLL
System.Type t = ass.GetType("Test.MyClass");//获得类型 string name = typeof(MyClass).AssemblyQualifiedName;
System.Type t1 = Type.GetType(name);
System.Type t2 = typeof(MyClass); object o = System.Activator.CreateInstance(t);//创建实例
System.Reflection.MethodInfo mi = t.GetMethod("Fun_1");//获得方法
mi.Invoke(o, new object[] { this.Page, "alert('测试反射机制')" });//调用方法 System.Reflection.MethodInfo mi1 = t.GetMethod("Fun_2");
mi1.Invoke(t, new object[] { this.Page, "alert('测试反射机制1')" });//调用方法
}
// 获取某个类的所有子类
var allTypes = Assembly.Load("Assembly-CSharp").GetTypes();
var childTypes = allTypes.Where(type => type.IsSubclassOf(typeof(ParentType))).ToList();
动态创建类
(待编辑)
动态编译,参考这篇文章:http://www.cnblogs.com/lichdr/archive/2004/10/20/54569.html
反射与工厂模式
(待编辑)
参考文章:
http://www.cnblogs.com/binfire/archive/2013/01/17/2864887.html
http://blog.sina.com.cn/s/blog_62b0d0ef0101e5ni.html
C# 反射研究的更多相关文章
- Java反射机制深入研究
ava 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? ...
- RazorEngine性能研究(反射的延深)
先说下结论 1)RazorEngine 确实很慢,编译过程特别慢,编译过后仍不适合大量重复调用的情况(一次调用可以接受). 2 ) RazorEngine 和 asp.net mvc 里的Razo ...
- 【java】java反射 Field类的研究使用
java反射 Field类的研究使用 user.getClass().getFields() 和 user.getClass().getDeclaredFields(); 的区别是什么?
- Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究
Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: 反射的概念是由Smith在1982年首次提出的 ...
- org.reflections 接口通过反射获取实现类源码研究
org.reflections 接口通过反射获取实现类源码研究 版本 org.reflections reflections 0.9.12 Reflections通过扫描classpath,索引元数据 ...
- 关于 CSS 反射倒影的研究思考
原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...
- Java反射机制学习与研究
Java反射机制:可以获取正在运行时的Java对象. 1.判断运行时对象对象所属的类. 2.判断运行时对象所具有的成员变量和方法. 3.还可以调用到private方法,改变private变量的值. S ...
- 获取对象属性类型、属性名称、属性值的研究:反射和JEXL解析引擎
同步发布:http://www.yuanrengu.com/index.php/20170511.html 先简单介绍下反射的概念:java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所 ...
- Java反射API研究(3)——java.lang.Class<T>
对于反射来说,Class是核心,任何反射的对象都需要通过Class来获得. Class 类的实例表示正在运行的 Java 应用程序中的类和接口.枚举是一种类,注释是一种接口.每个数组属于被映射为 Cl ...
随机推荐
- PriorityQueue和Queue的一种变体的实现
队列和优先队列是我们十分熟悉的数据结构.提供了所谓的“先进先出”功能,优先队列则按照某种规则“先进先出”.但是他们都没有提供:“固定大小的队列”和“固定大小的优先队列”的功能. 比如我们要实现:记录按 ...
- [转载]跨域iframe高度自适应
场景: 经常会有这样的需求,跟外部合作伙伴合作,要嵌入别人的页面,这时候就需要高度自适应了,在这种跨域的情况下如何解决呢? 解决: 在iframe(合作伙伴的页面,称为P页面)中创建一个隐藏的ifra ...
- 萌新笔记——git的问题(error: object file .git/objects/* is empty...)的解决方案及对git版本库文件的了解
由于操作不当,导致git版本库出了大问题,如下所示: error: object file .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e ...
- Morris post order traversal algorithm
Sept. 5, 2015 花时间把代码读明白, 比光看书强. 动手写代码, 改代码, 兴趣是最好的老师. 多记几个例子, 增加情趣. 举个例子关于中序遍历, 4 ...
- 1869: Mathematics and Geometry
这是郑州轻工业学校的一次校赛的校内选拔赛,看名字是计算几何 的题 题目地址: http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1869 Descript ...
- ios开发中的小技巧
在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新. UITableView的Group样式下顶部空白处理 //分组列表头部空白处理 UIView *view = [[UIViewal ...
- Maven与Ant比较
Maven与Ant比较 0 « 上一篇:Jenkins学习三:介绍一些Jenkins的常用功能» 下一篇:Jenkins学习四:Jenkins 邮件配置 posted @ 2015-03-25 16: ...
- Openjudge 1.13-23:区间内的真素数(每日一水)
总时间限制: 1000ms 内存限制: 65536kB 描述 找出正整数 M 和 N 之间(N 不小于 M)的所有真素数.真素数的定义:如果一个正整数 P 为素数,且其反序也为素数,那么 P 就为 ...
- docker学习(8) 在mac机上搭建私有仓库
docker的私有仓库类似maven的私服,一般用于公司内部搭建一个类似docker hub的环境,这样上传.下载镜像速度较快,本文将演示如何在mac上利用docker-machine搭建无需SSL证 ...
- [LeetCode] Repeated DNA Sequences 求重复的DNA序列
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACG ...