通过表达式目录树拼装lambda表达式,来实现两个类型的复制

一、下面的方法实现两个类型间的值复制

    /// <summary>
    /// 交换两个类型的属性(复制)
    /// </summary>
    /// <typeparam name="Tin"></typeparam>
    /// <typeparam name="Tout"></typeparam>
    public static class ExpressionCopy<Tin, Tout>
    {
        public static Tout Excharnge(Tin tin)
        {
            ParameterExpression experssionin = Expression.Parameter(typeof(Tin), "tModel");//创建实例
            List<MemberBinding> memberList = new List<MemberBinding>();//通过绑定用的
            foreach (var item in typeof(Tout).GetFields())//遍历所有的共有字段
            {
                FieldInfo field = typeof(Tin).GetField(item.Name.GetPropertyRemark(typeof(Tout), 1));
                if (field != null)
                {
                    MemberExpression member = Expression.Field(experssionin, field);
                    MemberBinding binding = Expression.Bind(item, member);
                    memberList.Add(binding);
                }
            }  

            foreach (var item in typeof(Tout).GetProperties())//遍历属性
            {
                PropertyInfo pro = typeof(Tin).GetProperty(item.Name.GetPropertyRemark(typeof(Tout), 2));//判断属性是否存在
                if (pro != null)
                {
                    MemberExpression proper = Expression.Property(experssionin, pro);
                    MemberBinding binding = Expression.Bind(item, proper);
                    memberList.Add(binding);
                }  

            }  

            MemberInitExpression init = Expression.MemberInit(Expression.New(typeof(Tout)), memberList.ToArray());//初始化绑定新成员
            Expression<Func<Tin, Tout>> lambda = Expression.Lambda<Func<Tin, Tout>>(init, new ParameterExpression[]
            {
            experssionin
            });
            return lambda.Compile().Invoke(tin);
        }
    }  

二、声明特性为了防止当要复制的属性字段不一致

/// <summary>
    /// 特性
    /// </summary>
    public class GetRemarkAttribute : Attribute
    {
        public GetRemarkAttribute(string name)
        {
            this._remark = name;
        }
        private string _remark;
        public string GetRemark()
        {
            return _remark;
        }
    }  

三、通过反射为string类型添加一个扩展方法,来获取特性的值

 1 public static class GetRemark
 2    {
 3        /// <summary>
 4        /// 通过反射获得特性
 5        /// </summary>
 6        /// <param name="values">字段属性名称</param>
 7        /// <param name="type">类型</param>
 8        /// <param name="parameter">参数1为字段2为属性</param>
 9        /// <returns></returns>
10        public static string GetPropertyRemark(this string values, Type type, int parameter)
11        {
12            if (parameter == 1)
13            {
14                FieldInfo propperty = type.GetField(values);
15
16                if (propperty.IsDefined(typeof(GetRemarkAttribute)))
17                {
18                    GetRemarkAttribute remark = (GetRemarkAttribute)propperty.GetCustomAttribute(typeof(GetRemarkAttribute));
19                    return remark.GetRemark();
20                }
21
22            }
23            else
24            {
25                PropertyInfo propperty = type.GetProperty(values);
26
27                if (propperty.IsDefined(typeof(GetRemarkAttribute)))
28                {
29                    GetRemarkAttribute remark = (GetRemarkAttribute)propperty.GetCustomAttribute(typeof(GetRemarkAttribute));
30                    return remark.GetRemark();
31                }
32
33            }
34            return values;
35
36        }
37    }  

四、下面就是实际操作调用

 1 public class OldPersoninfo
 2     {
 3         public int Id { get; set; }
 4         public string Name { get; set; }
 5         public string Type { get; set; }
 6         public OldPersoninfo()
 7         {
 8             Id = 2;
 9             Name = "测试";
10             Type = "非常类额";
11         }
12     }
13     public class NewPersoninfo
14     {
15         public int Id { get; set; }
16        // [GetRemark("Name")]
17         public string newName { get; set; }
18         //[GetRemark("Type")]
19         public string newType { get; set; }
20     }
21
22
23 private void test_Load(object sender, EventArgs e)
24        {
25            OldPersoninfo old = new OldPersoninfo();
26            NewPersoninfo newPersoninfo = ExpressionCopy<OldPersoninfo, NewPersoninfo>.Excharnge(old);
27            MessageBox.Show(newPersoninfo.newType);
28        }  

原文地址:https://www.cnblogs.com/xiaojunwu/p/11811829.html

时间: 2024-09-30 16:51:00

通过表达式目录树拼装lambda表达式,来实现两个类型的复制的相关文章

Lambda创建表达式目录树

一,如下代码: using System; using System.Linq.Expressions; namespace Demo { class Program { static void Main(string[] args) { Func<int, int, int> func = null; //两个参数 ParameterExpression a = Expression.Parameter(typeof(int), "a"); ParameterExpres

表达式目录树Expression

表达式目录树是用于动态的linq语句的拼装在以前遇到数据筛选的情况下我们日常的操作是 1 Console.WriteLine("输入Name 不写为空"); 2 var name = Console.ReadLine(); 3 Console.WriteLine("输入PassWord 不写为空"); 4 var PassWord = Console.ReadLine(); 5 string sql = "select * from Student whe

C# Lambda表达式详解,及Lambda表达式树的创建

最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介.优雅. Lambda表达式 "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内联表达式.所有Lambda表达式都使

dnspy的详细配置,dnspy如何过滤反编译之后的乱码,dnspy如何反编译表达式目录树

dnSpy应该是目前使用最多的.net反编译工具.很多情况下反编译C#代码非常方便,特别是查找基类,子类.搜索一些class,方法.接口,非常方便.比ILspy好很多.而且dnspy是可以配置的. 如果要dnSpy非常干净地显示反编译之后的代码,可以看我具体的配置: 第一张是效果图,过滤一个具体的关键词筛选的时候可以使用[全词匹配],可以在所有的.net framework中查找你需要寻找的那个关键字,不区分大小写. 右侧底部的这个搜索框是可以配置的,而且有时候很容易被隐藏掉,需要"上拉&quo

.Net工具类--表达式目录树解析DataReader和DataTable

一.概述 在项目中经常会使用SQL去操作数据库,在读取数据的时候返回结果一般是DataReader和DataSet,其中DataaSet里面可以包含多个DataTable. 读取到数据之后,一般情况下,我们需要把DataReader和DataSet解析成另外的数据实体和数据集合,有人会选择反射.硬编码,这些都是解决方案, 其实还有其他的解决方案,那就是表达式目录树. 二.解析DataReader 这个是生成表达式的方法. /// <summary> /// SqlDataReader生成表达式

第十九节: 结合【表达式目录树】来封装EF的BaseDal层的方法

一. 简介 该章节,可以说是一个简单轻松的章节,只要你对Expression表达式树.EF的基本使用.泛型有所了解,那么本章节实质上就是一个非常简单的封装章节,便于我们快捷开发. PS:在该章节对于EF的DB上下文怎么处理,怎么来的,不做介绍,在后续的框架篇将详细介绍. 如果你对Expression.EF的增删改查.泛型生疏的话,可以先阅读以下章节: (1). Expression表达式目录树:http://www.cnblogs.com/yaopengfei/p/7486870.html (2

根据表达式树动态生成Lambda表达式

1.准备 环境:Asp.Net MVC5 .EF6 前置知识:反射.使用过EF编写过Lambda表达式 2.基础类库 2.1该高级条件的类型 1 /// <summary> 2 /// 当前条件所属类型 3 /// </summary> 4 public enum Em_AS_ConditionType 5 { 6 /// <summary> 7 /// 并 8 /// </summary> 9 [Description("并")] 10

part01.03 委托与 Lambda 表达式(三):Lambda 表达式

"Lambda 表达式"是一个匿名函数,它可以包含表达式和语句,用于创建委托或表达式树类型 A. 用Lambda表达式代替匿名方法,复杂冗长的形式 格式:( 显式类型参数列表 )=>{ 语句 } 样例: // 带返回值的委托 Func<int, double, double> a = (m, n) => { return m * n; }; Console.WriteLine(a); Console.WriteLine(a(10, 25.2)); // 不带返回

Java 8 新特性:Lambda 表达式之方法引用(Lambda 表达式补充版)——诺诺&quot;涂鸦&quot;记忆

----------   诺诺学习技术交流博客.期待与您交流!    ---------- 详情请查看:http://blog.csdn.net/sun_promise  方法引用 (注:此文乃个人查找资料然后学习总结的,若有不对的地方,请大家指出,非常感谢!) 1.方法引用简述 方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法.方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文.计算时,方法引用会创建函数式接口的一个实例. 当Lambda表达式中