简单代码示例:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using System.Data; 8 using KaiCommon; 9 using System.Reflection; 10 using KaiCommon.ORM; 11 using System.Linq.Expressions; 12 using System.Reflection.Emit; 13 14 public delegate void PropertySetter < T > (T value); 15 public delegate T PropertyGetter < T > (); 16 17 public partial class Tools_TestGrid : System.Web.UI.Page 18 { 19 #region 泛型委托实现 20 public PropertyGetter < int > PropGet; 21 public PropertySetter < int > PropSet; 22 public void BuildSetMethod(TestData td) 23 { 24 Type t = td.GetType(); 25 PropertyInfo pi = t.GetProperty( " Name " ); 26 MethodInfo setter = pi.GetSetMethod(); 27 28 PropSet = (PropertySetter < int > )Delegate.CreateDelegate( typeof (PropertySetter < int > ), td, setter); 29 30 // string value = strPropGetter(); 31 } 32 33 public void BuildGetMethod(TestData td) 34 { 35 Type t = td.GetType(); 36 PropertyInfo pi = t.GetProperty( " Name " ); 37 MethodInfo getter = pi.GetGetMethod(); 38 39 PropGet = (PropertyGetter < int > )Delegate.CreateDelegate( typeof (PropertyGetter < int > ), td, getter); 40 41 // string value = strPropGetter(); 42 } 43 44 #endregion 45 46 #region 表达式树实现 47 Func < object , int > LmdGetProp; // Func<TestData, int> 48 public void LmdGet(Type entityType, string propName) 49 { 50 #region 通过方法取值 51 var p = entityType.GetProperty(propName); 52 // 对象实例 53 var param_obj = Expression.Parameter( typeof ( object ), " obj " ); 54 // 值 55 // var param_val = Expression.Parameter(typeof(object), "val"); 56 // 转换参数为真实类型 57 var body_obj = Expression.Convert(param_obj, entityType); 58 59 // 调用获取属性的方法 60 var body = Expression.Call(body_obj, p.GetGetMethod()); 61 LmdGetProp = Expression.Lambda < Func < object , int >> (body, param_obj).Compile(); 62 #endregion 63 64 #region 表达式取值 65 // var p = entityType.GetProperty(propName); 66 /// /lambda的参数u 67 // var param_u = Expression.Parameter(entityType, "u"); 68 /// /lambda的方法体 u.Age 69 // var pGetter = Expression.Property(param_u, p); 70 /// /编译lambda 71 // LmdGetProp = Expression.Lambda<Func<TestData, int>>(pGetter, param_u).Compile(); 72 #endregion 73 } 74 Action < object , object > LmdSetProp; 75 public void LmdSet(Type entityType, string propName) 76 { 77 var p = entityType.GetProperty(propName); 78 // 对象实例 79 var param_obj = Expression.Parameter( typeof ( object ), " obj " ); 80 // 值 81 var param_val = Expression.Parameter( typeof ( object ), " val " ); 82 // 转换参数为真实类型 83 var body_obj = Expression.Convert(param_obj, entityType); 84 var body_val = Expression.Convert(param_val, p.PropertyType); 85 // 调用给属性赋值的方法 86 var body = Expression.Call(body_obj, p.GetSetMethod(), body_val); 87 LmdSetProp = Expression.Lambda < Action < object , object >> (body, param_obj, param_val).Compile(); 88 89 } 90 #endregion 91 92 93 #region Emit动态方法实现 94 public delegate void SetValueDelegateHandler(TestData entity, object value); 95 public SetValueDelegateHandler EmitSetValue; 96 public void BuildEmitMethod(Type entityType, string propertyName) 97 { 98 // Type entityType = entity.GetType(); 99 Type parmType = typeof ( object ); 100 // 指定函数名 101 string methodName = " set_ " + propertyName; 102 // 搜索函数,不区分大小写 IgnoreCase 103 var callMethod = entityType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic); 104 // 获取参数 105 var para = callMethod.GetParameters()[ 0 ]; 106 // 创建动态函数 107 DynamicMethod method = new DynamicMethod( " EmitCallable " , null , new Type[] { entityType, parmType }, entityType.Module); 108 // 获取动态函数的 IL 生成器 109 var il = method.GetILGenerator(); 110 // 创建一个本地变量,主要用于 Object Type to Propety Type 111 var local = il.DeclareLocal(para.ParameterType, true ); 112 // 加载第 2 个参数【(T owner, object value)】的 value 113 il.Emit(OpCodes.Ldarg_1); 114 if (para.ParameterType.IsValueType) 115 { 116 il.Emit(OpCodes.Unbox_Any, para.ParameterType); // 如果是值类型,拆箱 string = (string)object; 117 } 118 else 119 { 120 il.Emit(OpCodes.Castclass, para.ParameterType); // 如果是引用类型,转换 Class = object as Class 121 } 122 il.Emit(OpCodes.Stloc, local); // 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。 123 il.Emit(OpCodes.Ldarg_0); // 加载第一个参数 owner 124 il.Emit(OpCodes.Ldloc, local); // 加载本地参数 125 il.EmitCall(OpCodes.Callvirt, callMethod, null ); // 调用函数 126 il.Emit(OpCodes.Ret); // 返回 127 /* 生成的动态函数类似: 128 * void EmitCallable(T owner, object value) 129 * { 130 * T local = (T)value; 131 * owner.Method(local); 132 * } 133 */ 134 135 EmitSetValue = method.CreateDelegate( typeof (SetValueDelegateHandler)) as SetValueDelegateHandler; 136 137 } 138 #endregion 139 140 protected void Page_Load( object sender, EventArgs e) 141 { 142 143 this .Response.Write( " 当前framework版本: " + Environment.Version.Major + " <br/> " ); 144 int max = 1000000 ; 145 this .Response.Write( " 循环次数: " + max + " <br/> " ); 146 if ( ! IsPostBack) 147 { 148 // 基本方法 149 DateTime time = DateTime.Now; 150 TestData d = new TestData(); 151 for ( int i = 0 ; i < max; i ++ ) 152 { 153 d.Name = i; 154 } 155 TimeSpan ts = DateTime.Now - time; 156 this .Response.Write( " 基本方法: " + ts.TotalMilliseconds + " <br/> " ); 157 158 // 反射方法 159 Type type = d.GetType(); 160 PropertyInfo pi = type.GetProperty( " Name " ); 161 time = DateTime.Now; 162 for ( int i = 0 ; i < max; i ++ ) 163 { 164 pi.SetValue(d, i, null ); 165 } 166 ts = DateTime.Now - time; 167 this .Response.Write( " 反射方法: " + ts.TotalMilliseconds + " <br/> " ); 168 169 // dynamic动态类型方法 170 dynamic dobj = Activator.CreateInstance < TestData > (); 171 time = DateTime.Now; 172 for ( int i = 0 ; i < max; i ++ ) 173 { 174 dobj.Name = i; 175 } 176 ts = DateTime.Now - time; 177 this .Response.Write( " dynamic动态类型方法: " + ts.TotalMilliseconds + " <br/> " ); 178 179 // 泛型委托赋值方法 180 d.Name = - 1 ; 181 BuildSetMethod(d); 182 time = DateTime.Now; 183 for ( int i = 0 ; i < max; i ++ ) 184 { 185 this .PropSet(i); 186 } 187 ts = DateTime.Now - time; 188 this .Response.Write( " 泛型委托赋值方法: " + ts.TotalMilliseconds + " <br/> " ); 189 this .Response.Write( " v: " + d.Name + " <br/> " ); 190 191 // 泛型委托取值方法 192 d.Name = - 1 ; 193 BuildGetMethod(d); 194 time = DateTime.Now; 195 for ( int i = 0 ; i < max; i ++ ) 196 { 197 this .PropGet(); 198 } 199 ts = DateTime.Now - time; 200 this .Response.Write( " 泛型委托取值方法: " + ts.TotalMilliseconds + " <br/> " ); 201 this .Response.Write( " v: " + d.Name + " <br/> " ); 202 203 // 表达式树赋值方法 204 d.Name = - 1 ; 205 LmdSet( typeof (TestData), " Name " ); 206 time = DateTime.Now; 207 for ( int i = 0 ; i < max; i ++ ) 208 { 209 this .LmdSetProp(d, i); 210 } 211 ts = DateTime.Now - time; 212 this .Response.Write( " 表达式树赋值方法: " + ts.TotalMilliseconds + " <br/> " ); 213 this .Response.Write( " v: " + d.Name + " <br/> " ); 214 215 // 表达式树取值方法 216 d.Name = - 132 ; 217 this .LmdGet( typeof (TestData), " Name " ); 218 time = DateTime.Now; 219 for ( int i = 0 ; i < max; i ++ ) 220 { 221 this .LmdGetProp(d); 222 } 223 ts = DateTime.Now - time; 224 this .Response.Write( " 表达式树取值方法: " + ts.TotalMilliseconds + " <br/> " ); 225 this .Response.Write( " v: " + this .LmdGetProp(d) + " <br/> " ); 226 227 // EMIT动态方法赋值 228 d.Name = - 1 ; 229 this .BuildEmitMethod(d.GetType(), " Name " ); 230 time = DateTime.Now; 231 for ( int i = 0 ; i < max; i ++ ) 232 { 233 this .EmitSetValue(d, i); 234 } 235 ts = DateTime.Now - time; 236 this .Response.Write( " EMIT动态方法: " + ts.TotalMilliseconds + " <br/> " ); 237 this .Response.Write( " v: " + d.Name + " <br/> " ); 238 239 // TestDataBind(); 240 } 241 } 242 243 } 244 245 public class TestData 246 { 247 public int Name { get ; set ; } 248 }
转载于:https://www.cnblogs.com/davidyang78/archive/2010/06/09/1754562.html
