反射的定義:審查元數(shù)據(jù)并收集關(guān)於它的類型信息的能力,元數(shù)據(jù)(編輯后的基本數(shù)據(jù)單元)就是一大堆表,編譯器會創(chuàng)建一個類定義表,一個字段定義表,一個方法定義表等,System.Reflection命名空間包含的幾個類,允許你反射(解析)這些元數(shù)據(jù)的代碼 一、反射的作用: 動態(tài)的創(chuàng)建類型的實例,將類型邦定到現(xiàn)有對象,或從現(xiàn)有對象中獲取類型 應(yīng)用程序需要在運行時從某個特定的程序集中載入一個特定的類型,以便實現(xiàn)某個任務(wù)時可以用到反射 反射主要應(yīng)用於類庫,這些類庫需要知道一個類型的定義,以便提供更多的功能 二、應(yīng)用要點: 現(xiàn)實應(yīng)用程序中很少使用到反射 使用反射動態(tài)邦定需要犧牲性能 有些元數(shù)據(jù)信息是不能通過反射獲取的 某些反射類型是專門為那些CLR開發(fā)編輯器開發(fā)使用的,所以你要意思到不是所有反射類型都是可以使用的 三、取得Assembly的方法: Assembly.Load Assembly.LoadFile Assembly.LoadFrom Type對象的Assembly方法 四、反射的成員: MemberInfo-成員 ConstructorInfo-結(jié)構(gòu) FieldInfo-字段 MethodInfo-方法 PropertyInfo-屬性 EventInfo-事件 五、根據(jù)反射取得對象的Member信息 private void WriteReflectionInfo() { Type testType = typeof(Test); Assembly assembly = testType.Assembly; Response.Write("Assembly:" + assembly.FullName + "<br/>"); Type[] typeList = assembly.GetTypes(); // 獲取類型 // 針對每個類型獲取詳細信息 foreach (Type type in typeList) { Response.Write("------------------------" + type.Namespace + type.Name + "------------------------<br/>"); // 獲得類型的結(jié)構(gòu)信息 ConstructorInfo[] constructs = type.GetConstructors(); // 獲得類型的字段信息 FieldInfo[] fields = type.GetFields(); Response.Write("<b>類的公共字段信息如下:</b>" + "<br/>"); int a1 = 1; foreach (FieldInfo field in fields) { Response.Write((a1++).ToString() + ". " + field.Name + "<br/>"); } // 獲得方法信息 MethodInfo[] methods = type.GetMethods(); Response.Write("<b>類的公共方法如下:</b>" + "<br/>"); int a2 = 1; foreach (MethodInfo method in methods) { ParameterInfo[] parameters = method.GetParameters(); ParameterInfo reparam = method.ReturnParameter; Response.Write((a2++).ToString() + ". " + reparam.ParameterType.Name + " " + method.Name + "("); int index = 0; foreach (ParameterInfo para in parameters) { if (index++ < parameters.Length - 1) Response.Write(para.ParameterType.Name + " " + para.Name + ","); else Response.Write(para.ParameterType.Name + " " + para.Name); } Response.Write(")<br/>"); } // 獲得屬性的信息 PropertyInfo[] propertys = type.GetProperties(); Response.Write("<b>類的公共屬性如下:</b>" + "<br/>"); int a3 = 1; foreach (PropertyInfo pro in propertys) { Response.Write((a3++).ToString() + ". " + pro.PropertyType.Name + " " + pro.Name + "{"); if (pro.CanRead) Response.Write("get;"); if (pro.CanWrite) Response.Write("set;"); Response.Write("}<br/>"); } // 獲得事件信息 EventInfo[] events = type.GetEvents(); Response.Write("<b>類的成員如下:</b>" + "<br/>"); // 獲得成員 int a4 = 1; foreach (MemberInfo mi in type.GetMembers()) { Response.Write((a4++).ToString() + ". " + mi.MemberType.ToString() + " : " + mi.Name + "<br/>"); } } 六、動態(tài)創(chuàng)建對象 Assembly對象的 CreateInstance方法 Activator. CreateInstance方法 Type對象的 InvokeMember方法 // 使用Assembly的CreateInstance方法來取得對象的實例 private void Assembly_CreateInstance() { string assemblyName = "SqlModel"; string className = assemblyName + ".Member"; // 創(chuàng)建無參數(shù)實例 IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className); Response.Write("創(chuàng)建無參數(shù)實例:" + member.ID + "<br/>"); // 創(chuàng)建有參數(shù)實例 Object[] parameters = new Object[1]; parameters[0] = 10000; IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className, false, BindingFlags.Default, null, parameters, null, null); Response.Write("創(chuàng)建有參數(shù)實例:" + member1.ID + "<br/>"); } // 使用Activator的CreateInstance方法來取得對象的實例 private void Activator_CreateInstance() { string assemblyName = "SqlModel"; string className = assemblyName + ".Member"; // 創(chuàng)建無參數(shù)實例 System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className); IDAL.IMember member = (IDAL.IMember)obj.Unwrap(); Response.Write("創(chuàng)建無參數(shù)實例:" + member.ID + "<br/>"); // 創(chuàng)建有參數(shù)實例 Object[] parameters = new Object[1]; parameters[0] = 10000; System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className, false, BindingFlags.CreateInstance, null, parameters, null, null, null); IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap(); Response.Write("創(chuàng)建有參數(shù)實例:" + member1.ID + "<br/>"); } // 使用Type的InvokeMember方法來取得對象的實例 private void Type_InvokeMember() { string assemblyName = "SqlModel"; string className = assemblyName + ".Member"; Assembly assem = Assembly.Load(assemblyName); Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的 // 創(chuàng)建無參數(shù)實例 IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, null); Response.Write("創(chuàng)建無參數(shù)實例:" + member.ID + "<br/>"); // 創(chuàng)建有參數(shù)實例 Object[] parameters = new Object[1]; parameters[0] = 10000; IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, parameters); Response.Write("創(chuàng)建有參數(shù)實例:" + member1.ID + "<br/>"); } 七、動態(tài)調(diào)用對象方法 Type對象的 InvokeMember方法 MethodInfo對象的Invoke方法 // Type對象的 InvokeMember方法來動態(tài)調(diào)用方法 private void InvokeMember() { string assemblyName = "SqlModel"; string className = assemblyName + ".Member"; string methodName = String.Empty; string result = String.Empty; Assembly assem = Assembly.Load(assemblyName); Object obj = assem.CreateInstance(className); Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的 // 動態(tài)調(diào)用無參數(shù)的方法 methodName = "GetName"; result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null); Response.Write(methodName + "方法的返回值:" + result + "<br/>"); // 動態(tài)調(diào)用有參數(shù)的方法 methodName = "Update"; Object[] methodParams = new Object[1]; methodParams[0] = DateTime.Now; result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams); Response.Write(methodName + "方法的返回值:" + result + "<br/>"); // 動態(tài)調(diào)用參數(shù)構(gòu)架函數(shù)的帶有參數(shù)的方法 Object[] parameters = new Object[1]; parameters[0] = 10000; obj = assem.CreateInstance(className,false,BindingFlags.CreateInstance, null, parameters, null, null); result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams); Response.Write(methodName + "方法的返回值:" + result + "<br/>"); } // MethodInfo對象的Invoke方法來動態(tài)調(diào)用方法 private void MethodInfo_Invoke() { string assemblyName = "SqlModel"; string className = assemblyName + ".Member"; string methodName = String.Empty; string result = String.Empty; Assembly assem = Assembly.Load(assemblyName); Object obj = assem.CreateInstance(className); Type type = assem.GetType(className); // 註意這里如果使用Type.GetType來取得Type的話,那麼assemblyName指定的類一定要是強命名的 // 動態(tài)調(diào)用無參數(shù)的方法 methodName = "GetName"; MethodInfo methodInfo = type.GetMethod(methodName); result = (string)methodInfo.Invoke(obj, null); Response.Write(methodName + "方法的返回值:" + result + "<br/>"); // 動態(tài)調(diào)用有參數(shù)的方法 methodName = "Update"; Object[] methodParams = new Object[1]; methodParams[0] = DateTime.Now; MethodInfo method = type.GetMethod(methodName); result = (string)method.Invoke(obj, methodParams); Response.Write(methodName + "方法的返回值:" + result + "<br/>"); } -------------------------------------------------------------------------------- 以上所使用的SqlModel.Member為: 新建一個SqlModel類庫,在其下建立一個Member的類 namespace SqlModel { public class Member : IDAL.IMember { private int _id = 100; public int ID { get { return _id; } set { _id = value; } } private string _name = "limin"; public string Name { get { return _name; } set { _name = value; } } public Member() { } public Member(int id) { _id = id; } private void Init() { } public string GetName() { return _name; } public string Update (DateTime cdate) { return "{" + String.Format("ID:{0},Name:{1},CreateDate:{2}",_id,_name,cdate) + "}"; } } } |
|