【转】 c# 反射 的一些基本知识
反射方面的基本知识:
① 什么是反射?
反射提供了封装程序集、模块和类型的对象。
.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息
Assembly类可以获得正在运行的装配件信息(.dll或.exe),也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。
Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。
MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。
诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。
② 命名空间与装配件的关系
很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。
命名空间类似与Java的包,但又不完全等同,因为Java的包必须按照目录结构来放置,命名空间则不需要。
装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。
装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在,这样说可能有点模糊.关系如同: 命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。
那么如果在编写程序的时候,也许不确定这个类在哪里(不知道在哪个装配件里),仅仅只是知道它的名称,就不能使用了吗?答案是可以,这就是反射了,就是在程序运行的时候提供该类型的地址,而去找到它。
一个简单的例子:
1. 自己写个类.用于测试反射用
新建一个C#类库项目,命名为TestReflect,
using System;
using System.Collections.Generic;
using System.Text;
//命名空间名字和类名最好不相同
namespace Song
{
public class TestReflect
{
public TestReflect() { }
public string Say(string s)
{
return "这不是静态方法:" + s;
}
public static string StaticSay(string s)
{
return "这是一个静态方法:" + s;
}
public string SayNoPara()
{
return "这个方法没有参数";
}
public string TwoParam(int i, int j)
{
return "有两个参数:" + i.ToString() + "和" + j.ToString();
}
}
}
将其编译为TestReflect.dll
2. 然后建立网站项目进行反射操作:源码如下
using System;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.Caching;
using System.Collections;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
try
{
System.Reflection.Assembly ass;
Type type;
Object obj;
ass = System.Reflection.Assembly.LoadFile(@"G:\CacheSample\TestReflect.dll");
//获取类TestReflect. 必须在某个装配件中寻找类
type = ass.GetType("Song.TestReflect");
System.Reflection.MethodInfo method = type.GetMethod("Say");
//创建一个类的实例
obj = ass.CreateInstance("Song.TestReflect");
//调用方法 public string Say(string s)
string s = (string)method.Invoke(obj, new string[] { "你好!" });
Response.Write(s+"<br/>");
//调用方法 public static string StaticSay(string s)
method = type.GetMethod("StaticSay");
Response.Write((string)method.Invoke(null, new string[] { "您好" }) + "<br/>");
//调用方法 public string SayNoPara()
method = type.GetMethod("SayNoPara");
Response.Write((string)method.Invoke(obj, null) + "<br/>");
//调用方法 public string TwoParam(int i, int j)
method = type.GetMethod("TwoParam");
Response.Write((string)method.Invoke(obj, new object[]{4, 5}) + "<br/>");
}
catch
{
}
}
}
}