• 比较两个相同类型的实例是否相同, 支持忽略指定字段.


    //翠花, 上代码
    
    var user1 = new User();
    user1.Id = 1;
    user1.Name = "翠花";
    user1.Age = 18;
    
    var user2 = new User();
    user2.Id = 2;
    user2.Name = "二狗";
    user2.Age = 19;
    
    //用法1
    var isEq1 = ObjectUtil.Compare(user1, user2, x=> x.Id);
    
    //用法2
    var isEq2 = ObjectUtil.Compare(user1, user2, x=> new{ x.Id, x.Age });
    public static class ObjectUtil
    {
        /// <summary>
        /// 比较两个同类型的实例是否相同,
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="t1"></param>
        /// <param name="t2"></param>
        /// <param name="ignore">忽略不比较的字段, 可以传入单个字段, 也可以传入匿名类 x=>{ x.Id } </param>
        /// <returns></returns>
        public static bool Compare<TEntity>(TEntity t1, TEntity t2, Expression<Func<TEntity, object>> ignore)
        {
            /*
             * 优化方向: 缓存通过反射取得的属性.
             */
    
            //取所有属性, 只取有{get;set;}的属性哦.
            var properties = (typeof(TEntity)).GetProperties();
    
            //拆解传入的表达式
            var ignoreProperty = Extract(ignore);
    
            //判断忽略模式, 是单字段还是多字段. 下面判断会不一样
            var isManyIgnore = ignoreProperty.Contains(",");
            if (isManyIgnore)
            {
                //加个逗号做边界,增加比较精准度.
                ignoreProperty = $",{ignoreProperty},";
            }
    
            foreach (var property in properties)
            {
                var pName = property.Name;
                if (isManyIgnore && ignoreProperty.Contains($",{pName},"))
                {
                    continue;
                }
                else
                {
                    if (ignoreProperty == pName)
                    {
                        continue;
                    }
                }
    
                var v1 = GetPropertyValue(t1, property);
                var v2 = GetPropertyValue(t2, property);
    
                //只要有一对字段不相等. 就结束循环. 后面的不用比了.
                if (!v1.Equals(v2))
                {
                    return false;
                }
            }
    
            return true;
        }
    
        #region 私有方法
        /*
         * 拆解表达式代码来自github项目52Chloe
         * 改造增加拆解匿名类表达式功能.
         * https://github.com/shuxinqin/Chloe/blob/481fcfd7ce260f7a31b0adde07311c5b25219829/src/Chloe/Entity/PropertyNameExtractor.cs
         */
        private static string Extract(Expression exp)
        {
            return Visit(exp);
        }
        private static string Visit(Expression exp)
        {
            switch (exp.NodeType)
            {
                case ExpressionType.Lambda:
                    return VisitLambda((LambdaExpression)exp);
                case ExpressionType.MemberAccess:
                    return VisitMemberAccess((MemberExpression)exp);
                case ExpressionType.Convert:
                    return VisitUnary_Convert((UnaryExpression)exp);
                case ExpressionType.New:
                    return VisitProperties(exp);
                default:
                    throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType));
            }
        }
        private static string VisitLambda(LambdaExpression exp)
        {
            return Visit(exp.Body);
        }
        private static string VisitMemberAccess(MemberExpression exp)
        {
            return exp.Member.Name;
        }
        private static string VisitUnary_Convert(UnaryExpression exp)
        {
            return Visit(exp.Operand);
        }
        private static string VisitProperties(object exp)
        {
            var members = ((NewExpression)exp).Members;
    
            if (members == null || members.Count == 0)
            {
                return string.Empty;
            }
    
            return string.Join(",", members.Select(p => p.Name).ToArray());
        }
        private static object GetPropertyValue<T>(T t, PropertyInfo property)
        {
            return property.GetValue(t);
        }
    
        #endregion
    }

    来都来了, 点个赞再走呗.↓

  • 相关阅读:
    20155209林虹宇虚拟机的安装及一点Linux的学习
    预备作业2林虹宇20155209
    预备作业01:你期望的师生关系是什么?
    20155203
    我眼中的师生关系以及对于专业学习的展望
    20155319的第一次随笔
    20155336 2016-2017-2《JAVA程序设计》第二周学习总结
    20155336 2016-2017-2《JAVA程序设计》第一周学习总结
    虎光元的第三次随笔
    20155336虎光元
  • 原文地址:https://www.cnblogs.com/adinet/p/12442632.html
Copyright © 2020-2023  润新知