• (转)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 }
  • 相关阅读:
    多线程、方便扩展的Windows服务程序框架
    C#并行开发_Thread/ThreadPool, Task/TaskFactory, Parallel
    C#并行编程-Task
    C#线程篇---Task(任务)和线程池不得不说的秘密(5)
    C# 线程知识--使用Task执行异步操作
    C# 线程池执行操作例子
    c#子线程执行完怎么通知主线程
    C#子线程执行完后通知主线程
    再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化
    熵的函数为什么用H,而熵的英文是entropy,好像没关系。实际原因是
  • 原文地址:https://www.cnblogs.com/helloEveryBody/p/5341515.html
Copyright © 2020-2023  润新知