反射其实就是为了能够在程序运行期间动态的加载一个外部的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# 反射/映射学习的更多相关文章

  1. JAVA反射机制—学习总结

    最近收到很多关于Java反射机制的问题留言,其实Java反射机制技术方面没有太多难点,或许是大家在学习过程中遗漏了细小知识点,导致一些问题无法彻底理解,现在我们简单的总结一下,加深印象.什么是反射机制 ...

  2. C#反射 入门学习 02

    获取Type类型的构造函数 前言                  有了前面的 C#反射 入门学习 01的知识,学习这篇估计是搓搓有余,它教会了我们获取方法的相关信息的两种形式与 使用反射调用方法,  ...

  3. JAVA的反射机制学习笔记(二)

    上次写JAVA的反射机制学习笔记(一)的时候,还是7月22号,这些天就瞎忙活了.自己的步伐全然被打乱了~不能继续被动下去.得又一次找到自己的节奏. 4.获取类的Constructor 通过反射机制得到 ...

  4. mybatis resultMap映射学习笔记

    这几天,百度mybatis突然看不到官网了,不知道百度怎么整的.特此贴出mybatis中文官网: http://www.mybatis.org/mybatis-3/zh/index.html 一个学习 ...

  5. C#反射深入学习

    C#反射 反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得 ...

  6. windows内存映射学习及帮助类实现

    本文通过创建文件内存映射类,学习windows内存映射相关知识:创建内存映射文件后,可以按照内存操作方式操作文件:支持32位程序处理超过4G大小的文件. 感谢http://blog.csdn.net/ ...

  7. 反射(学习整理)----Class类和加载器ClassLoader类的整理

    1.学习反射的时整理的笔记!Class类和ClassLoader类的简单介绍 反射机制中的Class Class内部到底有什么呢?看下图! 代码: Class cls=Person.class; .C ...

  8. C#反射 入门学习 01

    前言     获取方法的相关信息的两种形式 反射是一种允许用户获得类信息的C#功能,Type对象映射它代表的底层对象: 在.Net 中, 一旦获得了Type对象,就可以使用GetMethods()方法 ...

  9. PHP 反射类学习记录

    原文:http://www.upwqy.com/details/58.html 1 开发环境 windows TP5 参考文档 http://php.net/manual/zh/class.refle ...

随机推荐

  1. paper 98:图像视觉各个领域文献目录

    当前图像视觉各个领域文献资料的索引,包含计算机视觉.图像处理.文本(图像)分析.视频分析.模式识别等主题.如果对哪个方向比较感兴趣,可以查看这个方向的比较重要的Paper,每一个大的目录后面都对应一些 ...

  2. easyui datagrid将表头的checkbox不显示(隐藏)

    <script type="text/javascript"> $(function(){ $("#dg").datagrid({ url:&quo ...

  3. javascript中的自增与自减

    一直都对自增与自减的执行顺序有点糊涂,今天查了资料,来总结一下 a++(a--),就是指当时计算a,当下一次使用这个变量的时候才执行++或者-- ++a(--a),就是指当时就计算++或者-- 例1: ...

  4. BootStrap tabs标签 使用fade效果首次加载页面不能显示内容

    <div class="tab-pane active fade" id="home"> <div class="alert ale ...

  5. 使用匿名函数在回调函数中正确访问JS循环变量

    有时候, 需要以不同的参数调用某个URL,并且在回调函数中仍然可以访问正在使用的参数, 这时候, 需要使用闭包保存当前参数, 否则, 当回调函数执行时, 之前的参数很可能早已被修改为最后一个参数了. ...

  6. JavaScript encodeURI(), decodeURI(), encodeURIComponent(), decodeURIComponent()

    URI:  Uniform Resource Identifier encodeURI() And decodeURI() The encodeURI() function is used to en ...

  7. POJ 2876 Cantoring Along

    Description The Cantor set was discovered by Georg Cantor. It is one of the simpler fractals. It is ...

  8. Flowplayer-encoding

    SOURCE URL: https://flowplayer.org/docs/encoding.html Video encoding To ease the task of encoding yo ...

  9. Duilib实现QQ聊天窗口晃动

    转载:http://blog.csdn.net/arbboter/article/details/26282717 转载:http://blog.csdn.net/zerolusta/article/ ...

  10. web.xml配置详情 - 简要介绍

    <!--web.xml 元素简介--> <?xml version="1.0" encoding="UTF-8"?><web-ap ...