(转)C#反射机制详解
Posted helloEveryBody0821
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(转)C#反射机制详解相关的知识,希望对你有一定的参考价值。
1 反射的定义:审查元数据并收集关於它的类型信息的能力,元数据(编辑后的基本数据单元)就是一大堆表,编译器会创建一个类定义表,一个字段定义表,一个方法定义表等,System.Reflection命名空间包含的几个类,允许你反射(解析)这些元数据的代码 2 3 一、反射的作用: 4 动态的创建类型的实例,将类型邦定到现有对象,或从现有对象中获取类型 5 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射 6 反射主要应用於类库,这些类库需要知道一个类型的定义,以便提供更多的功能 7 8 二、应用要点: 9 现实应用程序中很少使用到反射 10 使用反射动态邦定需要牺牲性能 11 有些元数据信息是不能通过反射获取的 12 某些反射类型是专门為那些CLR开发编辑器开发使用的,所以你要意思到不是所有反射类型都是可以使用的 13 14 三、取得Assembly的方法: 15 Assembly.Load 16 Assembly.LoadFile 17 Assembly.LoadFrom 18 Type对象的Assembly方法 19 20 四、反射的成员: 21 MemberInfo-成员 22 ConstructorInfo-结构 23 FieldInfo-字段 24 MethodInfo-方法 25 PropertyInfo-属性 26 EventInfo-事件 27 28 五、根据反射取得对象的Member信息 29 private void WriteReflectionInfo() 30 { 31 Type testType = typeof(Test); 32 Assembly assembly = testType.Assembly; 33 Response.Write("Assembly:" + assembly.FullName + "<br/>"); 34 Type[] typeList = assembly.GetTypes(); // 获取类型 35 // 针对每个类型获取详细信息 36 foreach (Type type in typeList) 37 { 38 Response.Write("------------------------" + type.Namespace + type.Name + "------------------------<br/>"); 39 // 获得类型的结构信息 40 ConstructorInfo[] constructs = type.GetConstructors(); 41 42 // 获得类型的字段信息 43 FieldInfo[] fields = type.GetFields(); 44 Response.Write("<b>类的公共字段信息如下:</b>" + "<br/>"); 45 int a1 = 1; 46 foreach (FieldInfo field in fields) 47 { 48 Response.Write((a1++).ToString() + ". " + field.Name + "<br/>"); 49 } 50 51 // 获得方法信息 52 MethodInfo[] methods = type.GetMethods(); 53 54 Response.Write("<b>类的公共方法如下:</b>" + "<br/>"); 55 int a2 = 1; 56 foreach (MethodInfo method in methods) 57 { 58 ParameterInfo[] parameters = method.GetParameters(); 59 ParameterInfo reparam = method.ReturnParameter; 60 Response.Write((a2++).ToString() + ". " + reparam.ParameterType.Name + " " + method.Name + "("); 61 int index = 0; 62 foreach (ParameterInfo para in parameters) 63 { 64 if (index++ < parameters.Length - 1) 65 Response.Write(para.ParameterType.Name + " " + para.Name + ","); 66 else 67 Response.Write(para.ParameterType.Name + " " + para.Name); 68 } 69 Response.Write(")<br/>"); 70 } 71 72 // 获得属性的信息 73 PropertyInfo[] propertys = type.GetProperties(); 74 75 Response.Write("<b>类的公共属性如下:</b>" + "<br/>"); 76 int a3 = 1; 77 foreach (PropertyInfo pro in propertys) 78 { 79 Response.Write((a3++).ToString() + ". " + pro.PropertyType.Name + " " + pro.Name + "{"); 80 if (pro.CanRead) Response.Write("get;"); 81 if (pro.CanWrite) Response.Write("set;"); 82 Response.Write("}<br/>"); 83 } 84 // 获得事件信息 85 EventInfo[] events = type.GetEvents(); 86 87 Response.Write("<b>类的成员如下:</b>" + "<br/>"); 88 // 获得成员 89 int a4 = 1; 90 foreach (MemberInfo mi in type.GetMembers()) 91 { 92 Response.Write((a4++).ToString() + ". " + mi.MemberType.ToString() + " : " + mi.Name + "<br/>"); 93 } 94 } 95 96 六、动态创建对象 97 Assembly对象的 CreateInstance方法 98 Activator. CreateInstance方法 99 Type对象的 InvokeMember方法 100 // 使用Assembly的CreateInstance方法来取得对象的实例 101 private void Assembly_CreateInstance() 102 { 103 string assemblyName = "SqlModel"; 104 string className = assemblyName + ".Member"; 105 // 创建无参数实例 106 IDAL.IMember member = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className); 107 Response.Write("创建无参数实例:" + member.ID + "<br/>"); 108 // 创建有参数实例 109 Object[] parameters = new Object[1]; 110 parameters[0] = 10000; 111 IDAL.IMember member1 = (IDAL.IMember)Assembly.Load(assemblyName).CreateInstance(className, false, BindingFlags.Default, null, parameters, null, null); 112 Response.Write("创建有参数实例:" + member1.ID + "<br/>"); 113 } 114 115 // 使用Activator的CreateInstance方法来取得对象的实例 116 private void Activator_CreateInstance() 117 { 118 string assemblyName = "SqlModel"; 119 string className = assemblyName + ".Member"; 120 // 创建无参数实例 121 System.Runtime.Remoting.ObjectHandle obj = Activator.CreateInstance(assemblyName, className); 122 IDAL.IMember member = (IDAL.IMember)obj.Unwrap(); 123 Response.Write("创建无参数实例:" + member.ID + "<br/>"); 124 // 创建有参数实例 125 Object[] parameters = new Object[1]; 126 parameters[0] = 10000; 127 System.Runtime.Remoting.ObjectHandle obj1 = Activator.CreateInstance(assemblyName, className, false, BindingFlags.CreateInstance, null, parameters, null, null, null); 128 IDAL.IMember member1 = (IDAL.IMember)obj1.Unwrap(); 129 Response.Write("创建有参数实例:" + member1.ID + "<br/>"); 130 } 131 132 // 使用Type的InvokeMember方法来取得对象的实例 133 private void Type_InvokeMember() 134 { 135 string assemblyName = "SqlModel"; 136 string className = assemblyName + ".Member"; 137 Assembly assem = Assembly.Load(assemblyName); 138 Type type = assem.GetType(className); // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的 139 // 创建无参数实例 140 IDAL.IMember member = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, null); 141 Response.Write("创建无参数实例:" + member.ID + "<br/>"); 142 // 创建有参数实例 143 Object[] parameters = new Object[1]; 144 parameters[0] = 10000; 145 IDAL.IMember member1 = (IDAL.IMember)type.InvokeMember(className, BindingFlags.CreateInstance, null, null, parameters); 146 Response.Write("创建有参数实例:" + member1.ID + "<br/>"); 147 } 148 149 七、动态调用对象方法 150 151 Type对象的 InvokeMember方法 152 MethodInfo对象的Invoke方法 153 // Type对象的 InvokeMember方法来动态调用方法 154 private void InvokeMember() 155 { 156 string assemblyName = "SqlModel"; 157 string className = assemblyName + ".Member"; 158 string methodName = String.Empty; 159 string result = String.Empty; 160 Assembly assem = Assembly.Load(assemblyName); 161 Object obj = assem.CreateInstance(className); 162 Type type = assem.GetType(className); // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的 163 // 动态调用无参数的方法 164 methodName = "GetName"; 165 result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, null); 166 Response.Write(methodName + "方法的返回值:" + result + "<br/>"); 167 // 动态调用有参数的方法 168 methodName = "Update"; 169 Object[] methodParams = new Object[1]; 170 methodParams[0] = DateTime.Now; 171 result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams); 172 Response.Write(methodName + "方法的返回值:" + result + "<br/>"); 173 // 动态调用参数构架函数的带有参数的方法 174 Object[] parameters = new Object[1]; 175 parameters[0] = 10000; 176 obj = assem.CreateInstance(className,false,BindingFlags.CreateInstance, null, parameters, null, null); 177 result = (string)type.InvokeMember(methodName, BindingFlags.InvokeMethod, null, obj, methodParams); 178 Response.Write(methodName + "方法的返回值:" + result + "<br/>"); 179 } 180 181 // MethodInfo对象的Invoke方法来动态调用方法 182 183 private void MethodInfo_Invoke() 184 { 185 string assemblyName = "SqlModel"; 186 string className = assemblyName + ".Member"; 187 string methodName = String.Empty; 188 string result = String.Empty; 189 190 Assembly assem = Assembly.Load(assemblyName); 191 Object obj = assem.CreateInstance(className); 192 Type type = assem.GetType(className); // 註意这里如果使用Type.GetType来取得Type的话,那麼assemblyName指定的类一定要是强命名的 193 // 动态调用无参数的方法 194 methodName = "GetName"; 195 MethodInfo methodInfo = type.GetMethod(methodName); 196 result = (string)methodInfo.Invoke(obj, null); 197 Response.Write(methodName + "方法的返回值:" + result + "<br/>"); 198 // 动态调用有参数的方法 199 methodName = "Update"; 200 Object[] methodParams = new Object[1]; 201 methodParams[0] = DateTime.Now; 202 MethodInfo method = type.GetMethod(methodName); 203 result = (string)method.Invoke(obj, methodParams); 204 Response.Write(methodName + "方法的返回值:" + result + "<br/>"); 205 } 206 207 -------------------------------------------------------------------------------- 208 以上所使用的SqlModel.Member為: 209 新建一个SqlModel类库,在其下建立一个Member的类 210 211 namespace SqlModel 212 { 213 public class Member : IDAL.IMember 214 { 215 private int _id = 100; 216 public int ID 217 { 218 get { return _id; } 219 set { _id = value; } 220 } 221 private string _name = "limin"; 222 public string Name 223 { 224 get { return _name; } 225 set { _name = value; } 226 } 227 228 public Member() { } 229 public Member(int id) 230 { 231 _id = id; 232 } 233 234 private void Init() 235 { } 236 237 public string GetName() 238 { 239 return _name; 240 } 241 public string Update (DateTime cdate) 242 { 243 return "{" + String.Format("ID:{0},Name:{1},CreateDate:{2}",_id,_name,cdate) + "}"; 244 } 245 } 246 }
以上是关于(转)C#反射机制详解的主要内容,如果未能解决你的问题,请参考以下文章