标签:lin code set null rop soft class 说明 stat
使用Linq.Expressions来动态生成映射方法
1.我们先写个简单的类Test,包含一个ID和Name。
public class Test { public int? ID { get; set; } public string Name { get; set; } }
2.需要手工写简单映射代码,暂时不考虑大小写等问题,代码如下。
/// <summary> /// 设置属性 /// </summary> static void Set(Test t,string name,object value) { switch (name) { case "ID":t.ID = Convert.ToInt32(value);break; case "Name": t.Name = Convert.ToString(value); break; } } /// <summary> /// 获取属性 /// </summary> static Object Get(Test t, string name) { switch (name) { case "ID": return t.ID; case "Name": return t.Name; } return null; }
3.目标就是通过Expressions来自动产生上面2个方法,先定义Set方法的3个参数Test ,name,value(不了解Expressions点击)
ParameterExpression val = Expression.Parameter(typeof(object));//value ParameterExpression instance = Expression.Parameter(typeof(object));//Test ParameterExpression nameexp = Expression.Parameter(typeof(string));//name
4.通过反射得到所有的属性集合,再根据属性集合产生case 语句,以下为Set方法的表达式
var ps = t.GetProperties();//t为typeof(Test) List<SwitchCase> lt = new List<SwitchCase>(); foreach (var n in ps) { if (!n.CanWrite) { continue; } Expression tp = Expression.Convert(val, n.PropertyType); //类型转换,此为隐式转换。目前不考虑强行转换类型 lt.Add(Expression.SwitchCase(Expression.Call(Expression.Convert(instance, t), n.GetSetMethod(), tp), Expression.Constant(n.Name))); } Expression p1 = Expression.Switch(nameexp, lt.ToArray());
LambdaExpression exp = Expression.Lambda(p1, instance, nameexp, val);//转换为LambdaExpression 后就可以编译了
Action<object, string, object> act = exp.Compile() as Action<object, string, object>;
5.Get方法的表达式
var ps = t.GetProperties(); List<SwitchCase> lt = new List<SwitchCase>(); ParameterExpression instance = Expression.Parameter(typeof(object)); ParameterExpression nameexp = Expression.Parameter(typeof(string)); foreach (var n in ps) { if (!n.CanRead) { continue; } lt.Add(Expression.SwitchCase(Expression.Convert(Expression.Call(Expression.Convert(instance, t), n.GetGetMethod(), null), typeof(object)), Expression.Constant(n.Name))); } Expression p1 = Expression.Switch(nameexp, Expression.Constant(null), lt.ToArray()); LambdaExpression exp = Expression.Lambda(p1, instance, nameexp); Func<object, string, object> func = exp.Compile() as Func<object, string, object>;
以上只是简单的案例代码,用于说明Expression来产生映射代码,查看完整代码,虽然更多人用Emit,但本质是一样。
标签:lin code set null rop soft class 说明 stat
原文地址:https://www.cnblogs.com/xuzhiqiang/p/9495213.html