两个例子引入反射:
1、B超:大家体检的时候大概都做过B超吧,B超可以透过肚皮探测到你内脏的生理情况。这是如何做到的呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声波遇到内脏壁的时候就会产生一定的“回音”反射,然后把“回音”进行处理就可以显示出内脏的情况了(我不是医生也不是声学专家,不知说得是否准确^_^)。
2、地球内部结构:地球的内部结构大体可以分为三层:地壳、地幔和地核。地壳是固体,地核是液体,地幔则是半液半固的结构(中学地理的内容,大家还记得吧?)。如何在地球表面不用深入地球内部就知道其内部的构造呢?对,向地球发射“地震波”,“地震波”分两种一种是“横波”,另一种是“纵波”。“横波”只能穿透固体,而“纵波”既可穿透固体又可以穿透液体。通过在地面对纵波和横波的反回情况,我们就可以大体断定地球内部的构造了。
大家注意到这两个例子的共同特点,就是从一个对象的外部去了解对象内部的构造,而且都是利用了波的反射功能。在.NET中的反射也可以实现从对象的外部来了解对象(或程序集)内部结构的功能,哪怕你不知道这个对象(或程序集)是个什么东西,另外.NET中的反射还可以运态创建出对象并执行它其中的方法。
反射的用途:
使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。 使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
一:反射的定义
审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。
System.reflection命名空间包含的几个类,允许你反射(解析)这些元数据表的代码
System.Reflection.Assembly System.Reflection.MemberInfo System.Reflection.EventInfo System.Reflection.FieldInfo System.Reflection.MethodBase System.Reflection.ConstructorInfo System.Reflection.MethodInfo System.Reflection.PropertyInfo System.Type
层次模型:
二:获取类型信息
class MyClass
{
public string m
public void test() { }
public int MyProperty { get
}
//获取类型信息
protected void Button1_Click(object sender, EventArgs e)
{
Type type = typeof(MyClass)
Response
.Write(
"类型名:" + type
.Name)
Response
.Write(
"<br/>")
Response
.Write(
"类全名:" + type
.FullName)
Response
.Write(
"<br/>")
Response
.Write(
"命名空间名:" + type
.Namespace)
Response
.Write(
"<br/>")
Response
.Write(
"程序集名:" + type
.Assembly)
Response
.Write(
"<br/>")
Response
.Write(
"模块名:" + type
.Module)
Response
.Write(
"<br/>")
Response
.Write(
"基类名:" + type
.BaseType)
Response
.Write(
"<br/>")
Response
.Write(
"是否类:" + type
.IsClass)
Response
.Write(
"<br/>")
Response
.Write(
"类的公共成员:")
Response
.Write(
"<br/>")
MemberInfo[] memberInfos = type
.GetMembers()
foreach (var item
in memberInfos)
{
Response
.Write(string
.Format(
"{0}:{1}", item
.MemberType, item))
Response
.Write(
"<br/>")
}
}
三:获取程序集信息
protected void Button2_Click(object sender, EventArgs e)
{
//获取当前执行代码的程序集
Assembly assem = Assembly
.GetExecutingAssembly()
Response
.Write(
"程序集全名:"+assem
.FullName)
Response
.Write(
"<br/>")
Response
.Write(
"程序集的版本:"+assem
.GetName()
.Version)
Response
.Write(
"<br/>")
Response
.Write(
"程序集初始位置:"+assem
.CodeBase)
Response
.Write(
"<br/>")
Response
.Write(
"程序集位置:"+assem
.Location)
Response
.Write(
"<br/>")
Response
.Write(
"程序集入口:"+assem
.EntryPoint)
Response
.Write(
"<br/>")
Type[] types = assem
.GetTypes()
Response
.Write(
"程序集下包含的类型:")
foreach (var item
in types)
{
Response
.Write(
"<br/>")
Response
.Write(
"类:"+item
.Name)
}
}
四:反射调用方法
protected void Page_Load(object sender, EventArgs e)
{
System
.Reflection.Assembly ass = Assembly
.LoadFrom(AppDomain
.CurrentDomain.BaseDirectory+
"bin\\WebApplication1.dll")
System
.Type t = ass
.GetType(
"WebApplication1.MainPage")
string name=typeof(MainPage)
.AssemblyQualifiedName
System
.Type t1 = Type
.GetType(name)
System
.Type t2 = typeof(MainPage)
object o = System
.Activator.CreateInstance(t)
System
.Reflection.MethodInfo mi = t
.GetMethod(
"RunJs1")
mi
.Invoke(o, new object[] { this
.Page,
"alert('测试反射机制')" })
System
.Reflection.MethodInfo mi1 = t
.GetMethod(
"RunJs")
mi1
.Invoke(t, new object[] { this
.Page,
"alert('测试反射机制1')" })
}
五:反射调用用户/自定义控件
protected override void OnInit(EventArgs e)
{
CreateControl();
base.OnInit(e);
}
private void CreateControl()
{
Table tb =
new Table();
TableRow dr =
new TableRow();
TableCell cell =
new TableCell();
Control c = LoadControl(
"WebUserControl1.ascx");
cell.Controls.Add(c);
dr.Cells.Add(cell);
tb.Rows.Add(dr);
this.PlaceHolder1.Controls.Add(tb);
}
protected void Button1_Click(
object sender, EventArgs e)
{
foreach (TableRow tr
in PlaceHolder1.Controls[
0].Controls)
{
foreach (TableCell tc
in tr.Controls)
{
foreach (Control ctl
in tc.Controls)
{
if (ctl
is UserControl)
{
Type type = ctl.GetType();
System.Reflection.MethodInfo methodInfo = type.GetMethod(
"GetResult");
string selectedValue =
string.Concat(methodInfo.Invoke(ctl,
new object[] { }));
Response.Write(selectedValue);
break;
}
}
}
}
}
六:反射实现工厂模式
public partial class 反射 : System.Web.UI.Page
{
protected void Page_Load(
object sender, EventArgs e)
{
string typeName =
typeof(TestClass).AssemblyQualifiedName;
ITestInterface iface = RawGenericFactory.Create<ITestInterface>(typeName);
string result = iface.doSomething();
Response.Write(result);
}
}
public static class RawGenericFactory
{
public static T Create<T>(
string typeName)
{
return (T)Activator.CreateInstance(Type.GetType(typeName));
}
}
public interface ITestInterface
{
string doSomething();
}
public class TestClass : ITestInterface
{
public int Id {
get;
set; }
public override string ToString()
{
return Id.ToString();
}
public string doSomething()
{
return "ok";
}
}
七:自定义ORM框架
[Orm.Table(
"TestORM")]
public class TestORM
{
[Orm.Colum(
"Id",DbType.Int32)]
public int Id {
get;
set; }
[Orm.Colum(
"UserName", DbType.String)]
public string UserName {
get;
set; }
[Orm.Colum(
"Password", DbType.String)]
public string Password {
get;
set; }
[Orm.Colum(
"CreatedTime", DbType.DateTime)]
public DateTime CreatedTime {
get;
set; }
}
protected void Button3_Click(
object sender, EventArgs e)
{
TestORM t =
new TestORM()
{
Id=
1,
UserName=
"binfire",
Password=
"xxx",
CreatedTime=DateTime.Now
};
Orm.OrmHelp h=
new Orm.OrmHelp();
h.Insert(t);
}
namespace Orm
{
[AttributeUsageAttribute(AttributeTargets.Class, Inherited =
false, AllowMultiple =
false)]
public class TableAttribute : Attribute
{
private string _tableName;
public TableAttribute()
{
}
public TableAttribute(
string tableName)
{
this._tableName = tableName;
}
public string TableName
{
set
{
this._tableName =
value;
}
get
{
return this._tableName;
}
}
}
[AttributeUsageAttribute(AttributeTargets.Property, Inherited =
false, AllowMultiple =
false)]
public class ColumAttribute : Attribute
{
private string _columName;
private DbType _dbType;
public ColumAttribute()
{
}
public ColumAttribute(
string columName)
:
this()
{
this._columName = columName;
}
public ColumAttribute(
string columName, DbType dbType)
:
this(columName)
{
this._dbType = dbType;
}
public virtual string ColumName
{
set
{
this._columName =
value;
}
get
{
return this._columName;
}
}
public DbType DbType
{
get {
return _dbType; }
set { _dbType =
value; }
}
}
public class OrmHelp
{
public void Insert(
object table)
{
Type type = table.GetType();
Dictionary<
string,
string> columValue =
new Dictionary<
string,
string>();
StringBuilder SqlStr =
new StringBuilder();
SqlStr.Append(
"insert into ");
TableAttribute temp = (TableAttribute)type.GetCustomAttributes(
typeof(TableAttribute),
false).First();
SqlStr.Append(temp.TableName);
SqlStr.Append(
"(");
PropertyInfo[] Propertys = type.GetProperties();
foreach (
var item
in Propertys)
{
object[] attributes = item.GetCustomAttributes(
false);
foreach (
var item1
in attributes)
{
string value = table.GetType().InvokeMember(item.Name, System.Reflection.BindingFlags.GetProperty,
null, table,
null).ToString();
ColumAttribute colum = item1
as ColumAttribute;
if (colum !=
null)
{
columValue.Add(colum.ColumName,
value);
}
}
}
foreach (
var item
in columValue)
{
SqlStr.Append(item.Key);
SqlStr.Append(
",");
}
SqlStr.Remove(SqlStr.Length -
1,
1);
SqlStr.Append(
") values('");
foreach (
var item
in columValue)
{
SqlStr.Append(item.Value);
SqlStr.Append(
"','");
}
SqlStr.Remove(SqlStr.Length -
2,
2);
SqlStr.Append(
")");
HttpContext.Current.Response.Write(SqlStr.ToString());
}
}
}
http://www.cnblogs.com/binfire/archive/2013/01/17/2864887.html http://blog.csdn.net/educast/article/details/2894892