小寒的blog
Programming is a darned hard thing—but I am going to like it.

实现和上个用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();


 

posted on 2010-06-05 19:31  xhan  阅读(925)  评论(0编辑  收藏  举报