zoukankan      html  css  js  c++  java
  • Expression动态生成方法例子

    实现和上个用DynamicMethod的方式生成的复制实体类对应一样功能

    代码
    public  static class  ExpMapper<TTarget,TSource>
        {
            
    private static MapMethod<TTarget, TSource> mapMethod;
              
    public static MapMethod<TTarget, TSource> GetMapMethod()
            {
                
    if (mapMethod == null)
                {
                    mapMethod 
    = CreateMapMethod(typeof(TTarget), typeof(TSource));
                }
                
    return mapMethod;
            }

            
    public static TTarget Map(TSource source)
            {
                
    if (mapMethod == null)
                {
                    mapMethod 
    = CreateMapMethod(typeof(TTarget), typeof(TSource));
                }
                
    return mapMethod(source);     
            }

            
    private static MapMethod<TTarget, TSource> CreateMapMethod(Type targetType, Type sourceType)
            {
                var source 
    = Expression.Parameter(sourceType, "source");
       
                var binds 
    = (from sp in sourceType.GetProperties()
                                  from tp 
    in targetType.GetProperties()
                                  
    where sp.Name == tp.Name
                                  select Expression.Bind(tp, Expression.Property(source, sp))).ToArray();

                Expression body 
    = Expression.MemberInit(Expression.New(typeof(TTarget)), binds);

                
    return Expression.Lambda<MapMethod<TTarget, TSource>>(body,source).Compile();
                                 
            }

        }


     .net 4中添加了不少新的Expression。比如Expression.Assign用来赋值,Expression.Variable定义变量,等等用来生成代码会更加的直观。effective c# 第二版上有个例子

    代码如下

    代码
                var source = Expression.Parameter(typeof(TSource),"source");
                var dest 
    = Expression.Variable(typeof(TDest), "dest");
                var assignments 
    = from srcProp in typeof(TSource).GetProperties(BindingFlags.Public |BindingFlags.Instance)
                                  
    where srcProp.CanRead
                                  let destProp 
    = typeof(TDest).GetProperty(srcProp.Name,BindingFlags.Public |BindingFlags.Instance)
                                  
    where (destProp != null&&
                                  (destProp.CanWrite)
                                  select Expression.Assign(Expression.Property(dest,destProp),Expression.Property(source,srcProp));
                
    // put together the body:
                var body = new List<Expression>();
                body.Add(Expression.Assign(dest,Expression.New(
    typeof(TDest))));
                body.AddRange(assignments);
                body.Add(dest);
                var expr 
    =
                Expression.Lambda
    <Func<TSource, TDest>>(
                Expression.Block(
                
    new[] { dest }, // expression parameters
                body.ToArray() // body
                ),
                source 
    // lambda expression
                );
                var func 
    = expr.Compile();


  • 相关阅读:
    7月25 SVN 提交报错 | mybatis like | 数据库字段设计 | 打包打小包
    7月24 springboot 打包打小包 | mybatis 逆向工程 | 接口返回数据 | 启动打包注意事项 | springboot redis 引入
    7月20号 添加字段报错 | 密码加密与传输
    7月19 登录失败 错误次数 | 字段类型被修改bug | 日志
    7月14 Enity对象的抽取
    7月13 mybatis调用存储过程
    7月12 导入项目到svn | logback配置日志输出
    7月11 配置数据库自己挖坑 | 代码覆盖率测试 | MockMvc 测试用例
    书架
    试题库问题
  • 原文地址:https://www.cnblogs.com/xhan/p/1752375.html
Copyright © 2011-2022 走看看