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();


  • 相关阅读:
    P2420 让我们异或吧(倍增)
    bzoj题目分类
    hash练习们
    bzoj1433[ZJOI2009]假期的宿舍(匈牙利)
    bzoj2427:[HAOI2010]软件安装(Tarjan+tree_dp)
    bzoj2730矿场搭建(Tarjan割点)
    codevs4511信息传递(Tarjan求环)
    进入js
    css层叠样式表
    HTML超文本标记语言
  • 原文地址:https://www.cnblogs.com/xhan/p/1752375.html
Copyright © 2011-2022 走看看