.net反射
来源:互联网 发布:有声小说 知乎 编辑:程序博客网 时间:2024/05/24 23:13
转自:http://www.cnblogs.com/linzheng/archive/2010/12/13/1904661.html (原文更易阅读)
一、 反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类型于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型,并且对这些新类型的操作进行调用。
二、一些在反射中经常使用的类
Assembly类
Assembly类是可重用、无版本冲突并且可自我描述的公共语言运行库应用程序构造块。可以使用Assembly.Load和Assembly.LoadFrom方法动态地加载程序集。
Type类
反射的中心是System.Type类。System.Type类是一个抽象类,代表公用类型系统中的一种类型。这个类使您能够查询类型名、类型中包含的模块和名称空间、以及该类型是一个数值类型还是一个引用类型。
System.Type类使您能够查询几乎所有与类型相关的属性,包括类型访问限定符、类型是否、类型的COM属性等等。
Activator类
Activator类支持动态创建.NET程序集和COM对象。可以通过CreateComInstanceFrom、CreateInstance、CreateInstanceFrom、GetObject四个静态方法加载COM对象或者程序集,并能创建指定类型的实例。
Binder类
Binder类是一个用于执行类型转换的绑定器,Type对象的InvokeMember方法接受Binder对象,这个对象描述了如何将传递给InvokeMember的参数转换成方法实际需要的类型。
Binder类是一个抽象类,要创建绑定器,需要重写方法BindToMethod、BindToField、SelectMehtod、SelectProperty和ChangeType。
DefaultMemberAttribute类
DefaultMemberAttribute类用于类型并带有一个指明默认成员名称的字符串参数。能够通过InvokeMember调用默认成员,而不需要传递调用成员的名称。当需要绑定器但不需要特别的绑定行为时就可以使用它。
三、还有一些对元素类型信息描述的类,ConstrutorInfo(构造函数)、MethodInfo(方法)、FieldInfo(字段)、PropertyInfo(属性)、EventInfo(事件)、MemberInfo(成员)、ParameterInfo(参数)。如果查询得到了具有任何类型信息的实例,就可以获得该类型中任意元素的类型信息,当然出于安全原因,不保证会得到程序集中的任何信息。
四、示例
类定义
using System;using System.Collections.Generic;using System.Text;namespace ReflectionSample{ /**//**//**//// /// 说明:一个简单的类 /// 作者:文野 /// 联系:stwyhm.cnblog.com /// public class ClassSample { // 默认构造 public ClassSample() { this.name = "您调用了默认构造创建了一个类实例。"; } // 带参构造 public ClassSample(string name) { this.name = name; } // 字段 public string name; public string Field; // 属性 private string property; public string Property { set { this.property = value; } get { return property; } } // public方法 public string PublicClassMethod() { return string.Format("您反射了一个Public方法"); } // private方法 private string PrivateClassMethod() { return string.Format("您反射了一个Private方法"); } // static方法 public static string StaticMethod() { return "您反射了一个Static方法"; } // 帶參方法 public string ParameterMethod(string para) { return para; } public event EventHandler eventHandler; public void DoEvent() { eventHandler(null,EventArgs.Empty); } }}反射示例
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security;using System.Web.UI;using System.Web.UI.WebControls;using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls;using System.Reflection;using ReflectionSample;/**//**//**//// /// 说明:一个简单的使用反射示例/// 作者:文野/// 联系:stwyhm.cnblog.com/// public partial class _Default : System.Web.UI.Page{ protected void Page_Load(object sender, EventArgs e) { string path = Server.MapPath(Request.Path); string filePath = path.Substring(0, path.LastIndexOf(''\\'')) + @"\bin\ReflectionSample.dll"; // 获取程序集 Assembly classSampleAssembly = Assembly.LoadFrom(filePath); // 从程序集中获取指定对象类型 Type classSampleType = classSampleAssembly.GetType("ReflectionSample.ClassSample"); 使用Activator创建一个实例使用Activator创建一个实例#region 使用Activator创建一个实例 // 通过对象类型创建对象实例 ClassSample s1 = Activator.CreateInstance(classSampleType) as ClassSample; Response.Write(s1.name + "(使用Activator创建一个实例)"); #endregion 动态调用构造函数动态调用构造函数#region 动态调用构造函数 // 调用无参构造 ConstructorInfo studentConstructor1 = classSampleType.GetConstructor(new Type[] { }); ClassSample s2 = studentConstructor1.Invoke(new object[] { }) as ClassSample; Response.Write(s2.name + ""); // 调用有参构造 ConstructorInfo studentConstructor2 = classSampleType.GetConstructor(new Type[] { typeof(string) }); ClassSample s3 = studentConstructor2.Invoke(new object[] { "您调用了有参构造创建了一个类实例。" }) as ClassSample; Response.Write(s3.name + ""); #endregion 反射方法反射方法#region 反射方法 // 调用非静态方法 string returnValue1 = classSampleType.InvokeMember("PublicClassMethod", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] { }) as string; Response.Write(returnValue1 + ""); // 调用静态方法 string returnValue2 = classSampleType.InvokeMember("StaticMethod", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, s1, new object[] { }) as string; Response.Write(returnValue2 + ""); // 调用私有方法 string returnValue3 = classSampleType.InvokeMember("PrivateClassMethod", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, s1, new object[] { }) as string; Response.Write(returnValue3 + ""); #endregion //反射参数反射参数#region 反射参数 MethodInfo parameterMethod = classSampleType.GetMethod("ParameterMethod"); ParameterInfo[] paras = parameterMethod.GetParameters(); for (int i = 0; i ", new object[] { paras[i].Name, paras[i].ParameterType.ToString(), paras[i].IsOptional.ToString(), paras[i].Position.ToString(), paras[i].DefaultValue.ToString() })); #endregion //反射属性反射属性#region 反射属性 classSampleType.InvokeMember("Property", BindingFlags.SetProperty | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] { "您反射了一个属性" }); string returnValue4 = classSampleType.InvokeMember("Property", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] { }) as string; Response.Write(returnValue4 + ""); #endregion //反射字段反射字段#region 反射字段 classSampleType.InvokeMember("Field", BindingFlags.SetField | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] { "您反射了一个字段" }); string returnValue5 = classSampleType.InvokeMember("Field", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Instance, null, s1, new object[] { }) as string; Response.Write(returnValue5 + ""); #endregion }}
五、.net反射机制
使用反射机制是有一些缺点的。其最大的缺点就是编译器无法对对象进行类型检查,此时IDE的智能感知将无能为力。但是他的真正优势又在什么地方呢?它提供了一种手段,将指定具体类推迟到了运行时刻。
使用反射机制调用方法的四步曲:
1 加载程序集
2 获取类的类型
3 创建该类的实例
4 调用该实例的方法
System.Reflection.Assembly类中有两个静态方法Assembly.Load(string assemblyName)和Assembly.LoadFrom(string fileName)来把程序集加载到应用程序序域中。
PS:在。NET中当一个对象被创建时,幕后到底发生了什么?当我们运行某一个应用程序时,.NET CLR会首先创建一个应用程序域来容纳这个应用程序,接着将应该引用的程序集加载到应用程序域中。其中MSCorLib.dll是一个程序集,它包含了很多系统命名空间及其子命名空间中的类:System;System.Text,System.IO等。该程序集合中。然后CLR加载正在运行的应用程序所属的程序集。
DEMO:
(1)namespace ClassLibrarySport
{
public abstract class Sport
{
protected string name;
public abstract string GetName();
public abstract string GetDuration();
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == = == = =
(2)namespace ClassLibrarySomeSports //该项目添加了对(1)的引用
{
public class Football : ClassLibrarySport.Sport
{
public Football()
{
name = "Football";
}
public override string GetName()
{
return name;
}
public override string GetDuration()
{
return "four 15 minute quarters";
}
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == = == = =
(3)namespace ConsoleAssemblyTest //该项目添加了对(1)的引用
{
class Program
{
static void Main(string[] args)
{
Assembly assembly = Assembly.LoadFrom(@"E:\ClassLibrarySomeSports\
bin\Debug\ClassLibrarySomeSports.dll");
Type[] types = assembly.GetTypes();
Console.WriteLine("Get Type From ClassLibrarySomeSports.dll:");
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine(types[i].Name);
}
//使用GetConstructor()方法获取对应类型的构造器,从而构造出该类型的对象
Console.WriteLine("Use Method GetConstructor():");
ConstructorInfo ci = types[0].GetConstructor(new Type[0]);
ClassLibrarySport.Sport sport = (ClassLibrarySport.Sport)ci.Invoke(new object[0]);
Console.WriteLine(sport.GetName() + " has " + sport.GetDuration());
//使用Activator.CreateInstance()方法构造出该类型的对象
//使用assembly.CreateInstance()返回为null,??
Console.WriteLine("Use Method CreateInstance():");
ClassLibrarySport.Sport sport1 = (ClassLibrarySport.Sport)
Activator.CreateInstance(types[0]);
Console.WriteLine(sport1.GetName() + " has " + sport1.GetDuration());
//反射指定类型中的名称为“GetDuration”的方法,通过Invoke()方法执行该方法
object objSport = Activator.CreateInstance(types[0]);
MethodInfo method = types[0].GetMethod("GetDuration");
object o = method.Invoke(objSport, new object[0]);
Console.WriteLine(o as string);
Console.Read();
}
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == = == = =
Output:
Get Type From ClassLibrarySomeSports.dll:
Football
Use Method GetConstructor():
Football has four 15 minute quarters
Use Method CreateInstance():
Football has four 15 minute quarters
four 15 minute quarters
- .Net 反射
- .net反射
- .Net反射
- .net 反射
- .Net反射
- .NET反射
- net反射
- .net 反射
- .net 反射
- .net 反射
- .net反射
- .Net 反射
- .net反射
- 【.NET】反射
- net反射
- .Net 中的反射(反射特性)
- .Net 中的反射(反射特性)
- .net反射的问题。
- 浪潮国际机场云计算解决方案
- test
- Linux下查看tomcat版本
- MFC文件的读写操作
- ftp命令
- .net反射
- Jenkins+Ant+Android+TestNG+Robotium问题汇总及解决
- 深入理解maven及应用--转
- Lua中的元方法__newindex详解
- 正确使用Block避免Cycle Retain和Crash
- maven pom.xml详解
- Android 炫酷的ViewPagerIndicator 选项卡
- 学习<简明python教程>之个人总结
- 【BZOJ4004】【JLOI2015】装备购买 线性基