C# 反射/映射学习
反射其实就是为了能够在程序运行期间动态的加载一个外部的DLL集合,然后通过某种办法找到这个DLL集合中的某个空间下的某个类的某个成员(通过反射可以访问该类所包含的所有成员,不论成员是公有还是私有)
1.运用反射调用其它程序集中的方法:
假设另一个工程中的所有类都编译到一个dll文件中了,在这很多的类当中,有一个类叫StringUtil,名称空间在HSMP.CommonBasic.Common 代码如下 :
namespace lab.CommonBasic.Common
{
class StringUtil
{
public double GetSum(double x, double y)
{
return x + y;
}
}
}
编译后dll文件的存放路径是:D:\Test\HSMP.CommonBasic.dll
现在的问题是,如何通过程序调用该dll文件中的GetSum方法
大概有以下几步:
//这里要用LoadFrom,只有在本工程里添加了该dll的引用后才可以使用Load
Assembly objAss = Assembly.LoadFrom(@"D:\Test\HSMP.CommonBasic.dll"); //HSMP.CommonBasic.Common.StringUtil类的全路径
Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil"); //动态生成类StringUtil的实例
object obj = System.Activator.CreateInstance(t); //参数信息,GetSum需要两个int参数
System.Type[] paramTypes = new System.Type[];
paramTypes[] = System.Type.GetType("System.Int32");
paramTypes[] = System.Type.GetType("System.Int32"); //找到对应的方法
MethodInfo p = t.GetMethod("SayHello", paramTypes); // 也可以不给类型参数,下面调用时给实参就可以
MethodInfo p = t.GetMethod("SayHello"); //参数值,如果所调用的方法没有参数,不用写这些
Object[] parameters = new Object[];
parameters[] = ;
parameters[] = ; //如果没有参数,写null即可。
object objRetval = p.Invoke(obj, parameters);
通过代码可以看出反射其实很简单。就是动态类型加载。
以上我们用反射对静态类型做加载,但如果类是个范型类该怎么办呢?其实方法大同小异,只是获取到类型时需要设置一下实际要使用的类型即可,先看范型类定义:
namespace lab.CommonBasic.Common
{
class StringUtil<T,U>
{
public string GetSum(T x, U y)
{
return x + " and " + y;
}
}
}
再看反射操作:
... 前面代码相同
//HSMP.CommonBasic.Common.StringUtil类的全路径(范型类最后用 `2 标示需要2个范型类型参数)
Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2");
// 这一步很重要,设置实际的范型类型
t = t.MakeGenericType(new Type[] { typeof(string), typeof(string) });
//动态生成类StringUtil的实例
object obj = System.Activator.CreateInstance(t);
... 后面代码相同
还有一种情况,如果类是常类,但方法是范型方法改怎么办?非常简单:
... 前面代码相同
//HSMP.CommonBasic.Common.StringUtil类的全路径(范型类最后用 `2 标示需要2个范型类型参数)
Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2");
// 这一步要去掉,因为类不是泛型类所以不能给类设置范型类型
//t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) });
... 中间代码相同 // 区别在这里,把类级别的范型类型设置放到方法级别就可以了。 MethodInfo p = t.GetMethod("SayHello");
MethodInfo p = p.MakeGenericMethod(new Type[] { typeof(string), typeof(string) });
... 后面代码相同
2.动态加载, 更改, 增加...某个程序集
下面例子中, ChangeValue类的myValue本是私有字段,
一般情况下在类外部是不能改它的值的, 但利用反射就能直接访问私有字段而不需要通过包装器
class ChangeValue
{
// 这是私有字段
private string myValue; // 一般只有通过这样的公共属性外面才可能访问私有字段
public ChangeValue(string str)
{
myValue = str;
}
public void WriteLine()
{
Console.WriteLine("MyValue is: " + myValue);
}
} class Test
{
public static void Main(string[] args)
{
// 正常访问
ChangeValue cv = new ChangeValue("old value");
cv.WriteLine(); //反射的方法直接访问私有字段
Type t = cv.GetType(); //得到私有字段对象并赋值
FieldInfo field = t.GetField("myValue", BindingFlags.NonPublic | BindingFlags.Instance);
field.SetValue(cv, "new value"); //输出的是新值 "new value"
cv.WriteLine();
}
}
注:用反射加载的DLL必须要和项目同编译环境(即相同环境编译)
打个比方, 你要写一个播放器, 要支持如mp3, wmv, avi...等格式, 你还希望用户能自己安装一个新的格式, 也就是我们常说的插件.
在实现这些, 可能你要将每种格式都写成单个的解码程序集, 如 mp3.dll, wmv.dll, avi.dll.... 这样当播放时, 根据扩展名去动态调用相应的解码程序集, 那么这时你就得用反射去动态加载这些dll了.如: Assembly.LoadFile ("...avi.dll"), 然后通过反射可以用avi.dll里面定义的类了.
C# 反射/映射学习的更多相关文章
- JAVA反射机制—学习总结
最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象.什么是反射机制 ...
- C#反射 入门学习 02
获取Type类型的构造函数 前言 有了前面的 C#反射 入门学习 01的知识,学习这篇估计是搓搓有余,它教会了我们获取方法的相关信息的两种形式与 使用反射调用方法, ...
- JAVA的反射机制学习笔记(二)
上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了.自己的步伐全然被打乱了~不能继续被动下去.得又一次找到自己的节奏. 4.获取类的Constructor 通过反射机制得到 ...
- mybatis resultMap映射学习笔记
这几天,百度mybatis突然看不到官网了,不知道百度怎么整的.特此贴出mybatis中文官网: http://www.mybatis.org/mybatis-3/zh/index.html 一个学习 ...
- C#反射深入学习
C#反射 反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得 ...
- windows内存映射学习及帮助类实现
本文通过创建文件内存映射类,学习windows内存映射相关知识:创建内存映射文件后,可以按照内存操作方式操作文件:支持32位程序处理超过4G大小的文件. 感谢http://blog.csdn.net/ ...
- 反射(学习整理)----Class类和加载器ClassLoader类的整理
1.学习反射的时整理的笔记!Class类和ClassLoader类的简单介绍 反射机制中的Class Class内部到底有什么呢?看下图! 代码: Class cls=Person.class; .C ...
- C#反射 入门学习 01
前言 获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法 ...
- PHP 反射类学习记录
原文:http://www.upwqy.com/details/58.html 1 开发环境 windows TP5 参考文档 http://php.net/manual/zh/class.refle ...
随机推荐
- 设计模式_11_原型模式(prototype)深拷贝、浅拷贝
设计模式_11_原型模式(prototype) 浅拷贝: package designPatternOf23; /** * 定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象 * P ...
- Hdu 1443 Joseph
Joseph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- paper 100:何恺明经典去雾算法
一:由简至美的最佳论文(作者:何恺明 视觉计算组) [视觉机器人:个人感觉学习他的经典算法固然很重要,但是他的解决问题的思路也是非常值得我们学习的] 那是2009年4月24日的早上,我收到了一封不同 ...
- .NET中通過OUTLOOK發送附件內容
最近碰到一個發送郵件附件的問題,隨便幾下來,方便以後學習. string[] files = System.IO.Directory.GetFiles(@"~/UploadData" ...
- configure.ac:32: error: possibly undefined macro: AC_DEFINE
在ubuntu 下编译snappy时,在检查依赖关系时,处理autoconf的包时,在相关依赖包都已经安装的情况下,报如下错误,死活不过. configure.ac:32: error: possib ...
- Android 实例子源代码文件下载地址380个合集
android 城市列表特效 - 触摸查找源码 .rar: http://www.t00y.com/file/64337887 android 日记系统源码(数据库的基本操作) .rar: htt ...
- Dynamics AX 2012 R2 配置报表服务器
今天Reinhard在使用报表的过程中,发现以下错误: The default Report Server Configuration ID could not be found in the SRS ...
- windows进程详解
1:系统必要进程system process 进程文件: [system process] or [system process]进程名称: Windows内存处理系统进程描述: Windows ...
- C#MVC使用二进制流显示图片
关于显示图片的最好方法当然是img 的src直接指向地址,简单实用.但是有时候也会使用到使用图片流显示图片的方法.实现也比较简单(在C# mvc中,java的不了解).具体如下: 1.前台cshtml ...
- php : 获取对象的属性名
方案有多种: 一. 使用 get_object_vars() 方法 缺点: 只能显示 public 的 //只显示public的 var_dump(get_object_vars($test)); 处 ...