相关文章推荐
坚韧的绿茶  ·  VBA SolidWorks 二次开发 ...·  1 年前    · 
憨厚的毛衣  ·  html table ...·  1 年前    · 
逼格高的自行车  ·  excel - VBA: ...·  1 年前    · 
public delegate void PropertySetter<T> (T value); public delegate T PropertyGetter<T> (); public partial class Tools_TestGrid : System.Web.UI.Page #region 泛型委托实现 public PropertyGetter< int > PropGet; public PropertySetter< int > PropSet; public void BuildSetMethod(TestData td) Type t = td.GetType(); PropertyInfo pi = t.GetProperty( " Name " ); MethodInfo setter = pi.GetSetMethod(); PropSet = (PropertySetter< int >)Delegate.CreateDelegate( typeof (PropertySetter< int > ), td, setter); // string value = strPropGetter(); public void BuildGetMethod(TestData td) Type t = td.GetType(); PropertyInfo pi = t.GetProperty( " Name " ); MethodInfo getter = pi.GetGetMethod(); PropGet = (PropertyGetter< int >)Delegate.CreateDelegate( typeof (PropertyGetter< int > ), td, getter); // string value = strPropGetter(); #endregion #region 表达式树实现 Func < object , int > LmdGetProp; // Func<TestData, int> public void LmdGet(Type entityType, string propName) #region 通过方法取值 var p = entityType.GetProperty(propName); // 对象实例 var param_obj = Expression.Parameter( typeof ( object ), " obj " ); // var param_val = Expression.Parameter(typeof(object), "val"); // 转换参数为真实类型 var body_obj = Expression.Convert(param_obj, entityType); // 调用获取属性的方法 var body = Expression.Call(body_obj, p.GetGetMethod()); LmdGetProp = Expression.Lambda<Func< object , int >> (body, param_obj).Compile(); #endregion #region 表达式取值 // var p = entityType.GetProperty(propName); /// /lambda的参数u // var param_u = Expression.Parameter(entityType, "u"); /// /lambda的方法体 u.Age // var pGetter = Expression.Property(param_u, p); /// /编译lambda // LmdGetProp = Expression.Lambda<Func<TestData, int>>(pGetter, param_u).Compile(); #endregion Action < object , object > LmdSetProp; public void LmdSet(Type entityType, string propName) var p = entityType.GetProperty(propName); // 对象实例 var param_obj = Expression.Parameter( typeof ( object ), " obj " ); var param_val = Expression.Parameter( typeof ( object ), " val " ); // 转换参数为真实类型 var body_obj = Expression.Convert(param_obj, entityType); var body_val = Expression.Convert(param_val, p.PropertyType); // 调用给属性赋值的方法 var body = Expression.Call(body_obj, p.GetSetMethod(), body_val); LmdSetProp = Expression.Lambda<Action< object , object >> (body, param_obj, param_val).Compile(); #endregion #region Emit动态方法实现 public delegate void SetValueDelegateHandler(TestData entity, object value); public SetValueDelegateHandler EmitSetValue; public void BuildEmitMethod(Type entityType, string propertyName) // Type entityType = entity.GetType(); Type parmType = typeof ( object ); // 指定函数名 string methodName = " set_ " + propertyName; // 搜索函数,不区分大小写 IgnoreCase var callMethod = entityType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.NonPublic); // 获取参数 var para = callMethod.GetParameters()[ 0 ]; // 创建动态函数 DynamicMethod method = new DynamicMethod( " EmitCallable " , null , new Type[] { entityType, parmType }, entityType.Module); // 获取动态函数的 IL 生成器 var il = method.GetILGenerator(); // 创建一个本地变量,主要用于 Object Type to Propety Type var local = il.DeclareLocal(para.ParameterType, true ); // 加载第 2 个参数【(T owner, object value)】的 value il.Emit(OpCodes.Ldarg_1); if (para.ParameterType.IsValueType) il.Emit(OpCodes.Unbox_Any, para.ParameterType); // 如果是值类型,拆箱 string = (string)object; il.Emit(OpCodes.Castclass, para.ParameterType); // 如果是引用类型,转换 Class = object as Class il.Emit(OpCodes.Stloc, local); // 将上面的拆箱或转换,赋值到本地变量,现在这个本地变量是一个与目标函数相同数据类型的字段了。 il.Emit(OpCodes.Ldarg_0); // 加载第一个参数 owner il.Emit(OpCodes.Ldloc, local); // 加载本地参数 il.EmitCall(OpCodes.Callvirt, callMethod, null ); // 调用函数 il.Emit(OpCodes.Ret); // 返回 /* 生成的动态函数类似: * void EmitCallable(T owner, object value) * T local = (T)value; * owner.Method(local); EmitSetValue = method.CreateDelegate( typeof (SetValueDelegateHandler)) as SetValueDelegateHandler; #endregion protected void Page_Load( object sender, EventArgs e) this .Response.Write( " 当前framework版本: " + Environment.Version.Major + " <br/> " ); int max = 1000000 ; this .Response.Write( " 循环次数: " + max + " <br/> " ); if (! IsPostBack) // 基本方法 DateTime time = DateTime.Now; TestData d = new TestData(); for ( int i = 0 ; i < max; i++ ) d.Name = i; TimeSpan ts = DateTime.Now - time; this .Response.Write( " 基本方法: " + ts.TotalMilliseconds + " <br/> " ); // 反射方法 Type type = d.GetType(); PropertyInfo pi = type.GetProperty( " Name " ); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) pi.SetValue(d, i, null ); ts = DateTime.Now - time; this .Response.Write( " 反射方法: " + ts.TotalMilliseconds + " <br/> " ); // dynamic动态类型方法 dynamic dobj = Activator.CreateInstance<TestData> (); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) dobj.Name = i; ts = DateTime.Now - time; this .Response.Write( " dynamic动态类型方法: " + ts.TotalMilliseconds + " <br/> " ); // 泛型委托赋值方法 d.Name = - 1 ; BuildSetMethod(d); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) this .PropSet(i); ts = DateTime.Now - time; this .Response.Write( " 泛型委托赋值方法: " + ts.TotalMilliseconds + " <br/> " ); this .Response.Write( " v: " + d.Name + " <br/> " ); // 泛型委托取值方法 d.Name = - 1 ; BuildGetMethod(d); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) this .PropGet(); ts = DateTime.Now - time; this .Response.Write( " 泛型委托取值方法: " + ts.TotalMilliseconds + " <br/> " ); this .Response.Write( " v: " + d.Name + " <br/> " ); // 表达式树赋值方法 d.Name = - 1 ; LmdSet( typeof (TestData), " Name " ); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) this .LmdSetProp(d, i); ts = DateTime.Now - time; this .Response.Write( " 表达式树赋值方法: " + ts.TotalMilliseconds + " <br/> " ); this .Response.Write( " v: " + d.Name + " <br/> " ); // 表达式树取值方法 d.Name = - 132 ; this .LmdGet( typeof (TestData), " Name " ); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) this .LmdGetProp(d); ts = DateTime.Now - time; this .Response.Write( " 表达式树取值方法: " + ts.TotalMilliseconds + " <br/> " ); this .Response.Write( " v: " + this .LmdGetProp(d) + " <br/> " ); // EMIT动态方法赋值 d.Name = - 1 ; this .BuildEmitMethod(d.GetType(), " Name " ); time = DateTime.Now; for ( int i = 0 ; i < max; i++ ) this .EmitSetValue(d, i); ts = DateTime.Now - time; this .Response.Write( " EMIT动态方法: " + ts.TotalMilliseconds + " <br/> " ); this .Response.Write( " v: " + d.Name + " <br/> " ); // TestDataBind(); public class TestData public int Name { get ; set ; }