C#中的反射
C#中的反射一、什么是反射
Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型 (class)’组成,反射是.NET中的重要机制,通过反射,可以在运行时获得程序或程序集中每一个类型(包括类、结构、委托、接口和枚举等)的成员和成员的信息。有了反射,即可对每一个类型了如指掌。另外我还可以直接创建对象,即使这个对象的类型在编译时还不知道。
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
二、反射的用途:
(1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
(2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
(3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
(4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
(5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
(6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
(7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
(8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
(9)当您在一个应用程序域的仅反射上下文中工作时,请使用 CustomAttributeData 来发现有关自定义特性的信息。 通过使用 CustomAttributeData,您不必创建特性的实例就可以检查它们。
三、程序集的组成
四、反射的层次模型
五、通过反射获取类型信息
class MyClass
{
public string m;
public void test() { }
public int MyProperty { get; set; }
}
//获取类型信息
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"); //加载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 = <span style="color: rgb(255, 0, 0);">LoadControl("WebUserControl1.ascx");
</span> 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;
}
}
}
}
}