C#各种反射动态赋值取值方法

C#各种反射动态赋值取值方法

using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Data;
 using KaiCommon;
 using System.Reflection;
 using KaiCommon.ORM;
 using System.Linq.Expressions;
 using System.Reflection.Emit;
 
 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;
 }
 else
 {
 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; }
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值