//翠花, 上代码 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 }
来都来了, 点个赞再走呗.↓↓