C# 两个Object比较

C#两个Object进行比较,Object里只是简单属性,不存在层级关系还比较好处理,如果遇到多层级的就有点麻烦。

1、简单Object比较

        /// <summary>
        /// 比较字段
        /// </summary>
        /// <param name="beforeUpdateData">原来的值</param>
        /// <param name="afterUpdateData">页面提交的新值</param>
        /// <param name="specialFields">特殊处理字段</param>
        /// <param name="ignoreFields">忽略处理字段</param>
        /// <returns></returns>
        public static List<FieldItem> ComparisonField(Object beforeUpdateData,Object afterUpdateData,List<string> specialFields,List<string> ignoreFields)
        {
            var fieldItems = new List<FieldItem>();
            if (null == afterUpdateData || null == beforeUpdateData) return fieldItems;

            Type type = afterUpdateData.GetType();
            var fields = type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            foreach (var field in fields)
            {// 取得字段的值
                object afterUpdateItem = field.GetValue(afterUpdateData);
                var beforeUpdateItem = beforeUpdateData.GetType().GetProperty(field.Name).GetValue(beforeUpdateData, null);
          if (field.PropertyType.IsValueType || field.PropertyType.Name.StartsWith("String"))
                {
                    // String类型处理

                    // 直接比较是否相等,若不相等直接记录
                    if (afterUpdateItem.ToString() != beforeUpdateItem.ToString())
                    {
                        fieldItems.Add(new FieldItem
                                {
                                    ChangeField = field.Name,
                                    BeforeChangeContent = beforeUpdateItem.ToString(),
                                    AfterChangeContent = afterUpdateItem.ToString(),
                                    Description = "修改"
                                });
                    }
                }
            }        return fieldItems;
        }

2、复杂Object比较

对比 product 与 newProduct 两个Object,以下是修改项:

  1. 修改Name:小米Note -> 小米Note2
  2. 修改Detail中的Price:2299 -> 3399
  3. 修改耳机价格:79 -> 89
  4. 产品子项新增了米兔
    class Program
    {
        static void Main(string[] args)
        {
            var earphoneID = Guid.NewGuid();
            var rabbit = new ProductSubitem() { ID = Guid.NewGuid(), Name = "米兔", Detail = new Detail() { ID = Guid.NewGuid(), Introduce = "小米米兔", Price = 10 } };
            var subitem1 = new ProductSubitem() { ID = earphoneID, Name = "耳机", Detail = new Detail() { ID = Guid.NewGuid(), Introduce = "小米耳机", Price = 79 } };
            var subitem11 = new ProductSubitem() { ID = earphoneID, Name = "耳机", Detail = new Detail() { ID = Guid.NewGuid(), Introduce = "小米耳机", Price = 89 } };
            var subitem2 = new ProductSubitem() { ID = Guid.NewGuid(), Name = "手机贴膜", Detail = new Detail() { ID = Guid.NewGuid(), Introduce = "小米手机贴膜", Price = 5 } };

            // 构建产品原始数据
            var beijing = new Province { ID = Guid.NewGuid(), Name = "北京" };
            var mifan1 = new User() { ID = Guid.NewGuid(), UserName = "mifan1", RealName = "北京米粉" };
            var attachmentFiles = new List<AttachmentFile>()
                                      {
                                          new AttachmentFile(){ID = Guid.NewGuid(),Name = "说明书",SavePath = @"/xiaomi/document/note.doc",Size = 20}
                                      };

            var id = Guid.NewGuid();
            var detailID = Guid.NewGuid();
            var product = new Product()
                              {
                                  ID = id,
                                  Name = "小米Note",
                                  Detail = new Detail() { ID = detailID, Introduce = "小米新款手机", Price = 2299 },
                                  Province = beijing,
                                  CreateUser = mifan1,
                                  CreateTime = DateTime.Now,
                                  ProductSubitems = new List<ProductSubitem>() { subitem1, subitem2 },
                                  AttachmentFiles = attachmentFiles
                              };

            var newProduct = new Product()
            {
                ID = id,
                Name = "小米Note2", // 1.修改了Name:小米Note -> 小米Note2
                Detail = new Detail() { ID = detailID, Introduce = "小米新款手机", Price = 3399 }, // 2.修改了Detail中的Price:2299 -> 3399
                Province = beijing,
                CreateUser = mifan1,
                CreateTime = DateTime.Now,
                ProductSubitems = new List<ProductSubitem>() { rabbit, subitem11, subitem2 }, // 3.修改耳机价格:79 -> 89 | 4.产品子项新增了米兔。
                AttachmentFiles = attachmentFiles
            };

            var comparisonFieldList = Common.ComparisonField(product, newProduct, SpecialFields, IgnoreFields);
            foreach (var fieldItem in comparisonFieldList)
            {
                Console.WriteLine(string.Format("变更字段:{0}, 修改前内容:{1}, 修改后内容:{2}, 描述:{3}", fieldItem.ChangeField, fieldItem.BeforeChangeContent, fieldItem.AfterChangeContent,fieldItem.Description));
            }

            Console.ReadLine();
        }

        /// <summary>
        /// 特殊字段,只做ID比较
        /// </summary>
        public static readonly List<string> SpecialFields = new List<string>()
        {
            "Province","AttachmentFiles"
        };

        /// <summary>
        /// 忽略字段
        /// </summary>
        public static readonly List<string> IgnoreFields = new List<string>()
        {
            "ID",
            "CreateTime",
            "CreateUser"
        }; 

多层级实体:

  1         /// <summary>
  2         /// 产品
  3         /// </summary>
  4         public class Product
  5         {
  6             public Guid ID { get; set; }
  7
  8             /// <summary>
  9             /// 名称
 10             /// </summary>
 11             public string Name { get; set; }
 12
 13             /// <summary>
 14             /// 详情
 15             /// </summary>
 16             public Detail Detail { get; set; }
 17
 18             /// <summary>
 19             /// 产地
 20             /// </summary>
 21             public Province Province { get; set; }
 22
 23             /// <summary>
 24             /// 创建用户
 25             /// </summary>
 26             public User CreateUser { get; set; }
 27
 28             public DateTime CreateTime { get; set; }
 29
 30             /// <summary>
 31             /// 产品子项
 32             /// </summary>
 33             public List<ProductSubitem> ProductSubitems { get; set; }
 34
 35             /// <summary>
 36             /// 相关文件
 37             /// </summary>
 38             public List<AttachmentFile> AttachmentFiles { get; set; }
 39         }
 40
 41         /// <summary>
 42         /// 用户
 43         /// </summary>
 44         public class User
 45         {
 46             public Guid ID { get; set; }
 47
 48             public string UserName { get; set; }
 49
 50             public string RealName { get; set; }
 51         }
 52
 53         /// <summary>
 54         /// 省份
 55         /// </summary>
 56         public class Province
 57         {
 58             public Guid ID { get; set; }
 59
 60             public string Name { get; set; }
 61         }
 62
 63         /// <summary>
 64         /// 介绍
 65         /// </summary>
 66         public class Detail
 67         {
 68             public Guid ID { get; set; }
 69
 70             /// <summary>
 71             /// 介绍
 72             /// </summary>
 73             public string Introduce { get; set; }
 74
 75             /// <summary>
 76             /// 价格
 77             /// </summary>
 78             public double Price { get; set; }
 79         }
 80
 81         public class ProductSubitem
 82         {
 83             public Guid ID { get; set; }
 84
 85             public string Name { get; set; }
 86
 87             /// <summary>
 88             /// 详情
 89             /// </summary>
 90             public Detail Detail { get; set; }
 91         }
 92
 93         /// <summary>
 94         /// 文件(图片、文档)
 95         /// </summary>
 96         public class AttachmentFile
 97         {
 98             public Guid ID { get; set; }
 99
100             public string Name { get; set; }
101
102             public double Size { get; set; }
103
104             public string SavePath { get; set; }
105         }

多层级实体

最终匹配结果:

ComparisonField 完整方法:

  1 namespace ComparisonFieldTest
  2 {
  3     public class Common
  4     {
  5         /// <summary>
  6         /// 比较字段
  7         /// </summary>
  8         /// <param name="beforeUpdateData">原来的值</param>
  9         /// <param name="afterUpdateData">页面提交的新值</param>
 10         /// <param name="specialFields">特殊处理字段</param>
 11         /// <param name="ignoreFields">忽略处理字段</param>
 12         /// <returns></returns>
 13         public static
 14         List<FieldItem> ComparisonField(Object beforeUpdateData, Object afterUpdateData, List<string> specialFields, List<string> ignoreFields)
 15         {
 16             var fieldItems = new List<FieldItem>();
 17             if (null == afterUpdateData || null == beforeUpdateData)
 18                 return fieldItems;
 19
 20             Type type = afterUpdateData.GetType();
 21             var fields = type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
 22             foreach (var field in fields)
 23             {
 24                 // 忽略字段不处理
 25                 if (ignoreFields.Contains(field.Name))
 26                 {
 27                     continue;
 28                 }
 29
 30                 // 取得字段的值
 31                 object afterUpdateItem = field.GetValue(afterUpdateData);
 32                 var beforeUpdateItem = beforeUpdateData.GetType().GetProperty(field.Name).GetValue(beforeUpdateData, null);
 33
 34                 // 都为空不比较
 35                 if (afterUpdateItem == null && beforeUpdateItem == null)
 36                 {
 37                     continue;
 38                 }
 39
 40                 if (field.PropertyType.IsValueType || field.PropertyType.Name.StartsWith("String"))
 41                 {
 42                     // String类型处理
 43
 44                     // 直接比较是否相等,若不相等直接记录
 45                     if (afterUpdateItem.ToString() != beforeUpdateItem.ToString())
 46                     {
 47                         fieldItems.Add(new FieldItem
 48                         {
 49                             ChangeField = field.Name,
 50                             BeforeChangeContent = beforeUpdateItem.ToString(),
 51                             AfterChangeContent = afterUpdateItem.ToString(),
 52                             Description = "修改"
 53                         });
 54                     }
 55                 }
 56                 else if (field.PropertyType.IsGenericType)
 57                 {
 58                     // List类型处理
 59
 60                     var afterUpdateList = field.GetValue(afterUpdateData, null);
 61                     var beforeUpdateList = beforeUpdateData.GetType().GetProperty(field.Name).GetValue(beforeUpdateData, null);
 62
 63                     /*
 64                      * 判断两个对象是否一致,若一致说明未修改,若不一致说明有修改
 65                      * 修改有三种情况:新增,修改,删除,通过两次遍历找出
 66                      */
 67
 68                     var afterList = afterUpdateList as IEnumerable<object>;
 69                     var beforeList = beforeUpdateList as IEnumerable<object>;
 70
 71                     // 1.遍历新的与原数据比较
 72                     foreach (var afterObj in afterList)
 73                     {
 74                         Type tp = afterObj.GetType();
 75                         var property = tp.Name;
 76
 77                         var ID = afterObj.GetType().GetProperty("ID").GetValue(afterObj);
 78                         if (ID == null)
 79                         {
 80                             // 1. 新录入项
 81
 82                             if (specialFields.Contains(field.Name))
 83                             {
 84                                 // 新增,特殊处理字段
 85                                 fieldItems.Add(new FieldItem
 86                                 {
 87                                     ChangeField = property,
 88                                     BeforeChangeContent = string.Empty,
 89                                     AfterChangeContent = ID.ToString(),
 90                                     Description = "新增"
 91                                 });
 92                             }
 93                             else
 94                             {
 95                                 var properties = afterObj.GetType().GetProperties();
 96                                 var afterChangeContent = new StringBuilder();
 97                                 foreach (var propertyInfo in properties)
 98                                 {
 99                                     var propertyName = propertyInfo.Name;
100                                     var value = propertyInfo.GetValue(afterObj);
101                                     afterChangeContent.Append(propertyName + ":" + value + "; ");
102                                 }
103                                 var afterChangeContentStr = afterChangeContent.ToString().Substring(0, afterChangeContent.ToString().Length - 1);
104
105                                 fieldItems.Add(new FieldItem
106                                 {
107                                     ChangeField = property,
108                                     BeforeChangeContent = string.Empty,
109                                     AfterChangeContent = afterChangeContentStr,
110                                     Description = "新增"
111                                 });
112                             }
113                         }
114                         else
115                         {
116                             // 2.修改项
117
118                             if (!specialFields.Contains(field.Name))
119                             {
120                                 var beforeObj = beforeList.FirstOrDefault(b => b.GetType().GetProperty("ID").GetValue(b).ToString() == ID.ToString());
121                                 if (beforeObj != null)
122                                 {
123                                     // 1.判断两个对象是否一致,若一致不管,若不一致再处理
124
125                                     // 递归调用
126                                     var result = ComparisonField(beforeObj, afterObj, specialFields, ignoreFields);
127                                     if (result.Any())
128                                     {
129                                         // 修改操作
130                                         fieldItems.Add(new FieldItem
131                                         {
132                                             ChangeField = property,
133                                             BeforeChangeContent = string.Join(";", result.Select(t => t.ChangeField + ":" + t.BeforeChangeContent)),
134                                             AfterChangeContent = string.Join(";", result.Select(t => t.ChangeField + ":" + t.AfterChangeContent)),
135                                             Description = "修改"
136                                         });
137                                     }
138                                 }
139                                 else
140                                 {
141                                     var properties = afterObj.GetType().GetProperties();
142                                     var afterChangeContent = new StringBuilder();
143                                     foreach (var propertyInfo in properties)
144                                     {
145                                         var propertyName = propertyInfo.Name;
146                                         var value = propertyInfo.GetValue(afterObj);
147                                         afterChangeContent.Append(propertyName + ":" + value + "; ");
148                                     }
149                                     var afterChangeContentStr = afterChangeContent.ToString().Substring(0, afterChangeContent.ToString().Length - 1);
150
151                                     fieldItems.Add(new FieldItem
152                                     {
153                                         ChangeField = property,
154                                         BeforeChangeContent = string.Empty,
155                                         AfterChangeContent = afterChangeContentStr,
156                                         Description = "新增"
157                                     });
158                                 }
159                             }
160                         }
161                     }
162
163                     // 2.遍历原数据与新的比较
164                     foreach (var beforeObj in beforeList)
165                     {
166                         var ID = beforeObj.GetType().GetProperty("ID").GetValue(beforeObj);
167                         var afterObj = afterList.FirstOrDefault(b => b.GetType().GetProperty("ID").GetValue(b).ToString() == ID.ToString());
168                         if (afterObj == null)
169                         {
170                             // 删除操作
171
172                             if (specialFields.Contains(field.Name))
173                             {
174                                 // 删除,特殊处理字段
175                                 fieldItems.Add(new FieldItem
176                                 {
177                                     ChangeField = beforeObj.GetType().Name,
178                                     BeforeChangeContent = ID.ToString(),
179                                     AfterChangeContent = string.Empty,
180                                     Description = "删除"
181                                 });
182                             }
183                             else
184                             {
185                                 var properties = beforeObj.GetType().GetProperties();
186                                 var beforeContent = new StringBuilder();
187                                 foreach (var propertyInfo in properties)
188                                 {
189                                     var propertyName = propertyInfo.Name;
190                                     var value = propertyInfo.GetValue(beforeObj);
191                                     beforeContent.Append(propertyName + ":" + value + "; ");
192                                 }
193                                 var beforeContentStr = beforeContent.ToString()
194                                     .Substring(0, beforeContent.ToString().Length - 1);
195
196                                 fieldItems.Add(new FieldItem
197                                 {
198                                     ChangeField = beforeObj.GetType().Name,
199                                     BeforeChangeContent = beforeContentStr,
200                                     AfterChangeContent = string.Empty,
201                                     Description = "删除"
202                                 });
203                             }
204                         }
205                     }
206                 }
207                 else if (specialFields.Contains(field.Name))
208                 {
209                     // 特殊字段处理
210                     if (afterUpdateItem != null && beforeUpdateItem == null)
211                     {
212                         // 第一种情况:新增
213                         fieldItems.Add(new FieldItem
214                         {
215                             ChangeField = field.Name,
216                             BeforeChangeContent = string.Empty,
217                             AfterChangeContent = afterUpdateItem.GetType().GetProperty("ID").GetValue(afterUpdateItem, null).ToString(),
218                             Description = "新增"
219                         });
220                     }
221                     else if (afterUpdateItem == null && beforeUpdateItem != null)
222                     {
223                         // 第二种情况:删除
224                         fieldItems.Add(new FieldItem
225                         {
226                             ChangeField = field.Name,
227                             BeforeChangeContent = beforeUpdateItem.GetType().GetProperty("ID").GetValue(beforeUpdateItem, null).ToString(),
228                             AfterChangeContent = string.Empty,
229                             Description = "删除"
230                         });
231                     }
232                     else
233                     {
234                         // 第一种情况:修改
235                         var afterId = afterUpdateItem.GetType().GetProperty("ID").GetValue(afterUpdateItem, null);
236                         var beforeId = beforeUpdateItem.GetType().GetProperty("ID").GetValue(beforeUpdateItem, null);
237                         if (!afterId.Equals(beforeId))
238                         {
239                             fieldItems.Add(new FieldItem
240                             {
241                                 ChangeField = field.Name,
242                                 BeforeChangeContent = beforeId.ToString(),
243                                 AfterChangeContent = afterId.ToString(),
244                                 Description = "修改"
245                             });
246                         }
247                     }
248                 }
249                 else
250                 {
251                     // 递归调用
252                     var result = ComparisonField(beforeUpdateItem, afterUpdateItem, specialFields, ignoreFields);
253                     fieldItems.AddRange(result);
254                 }
255             }
256             return fieldItems;
257         }
258     }
259
260     /// <summary>
261     /// 建设项目变更字段记录
262     /// </summary>
263     public class FieldItem
264     {
265         /// <summary>
266         /// 变更字段
267         /// </summary>
268         public string ChangeField { get; set; }
269
270         /// <summary>
271         /// 修改前内容(针对建设图时,存储建设图ID)
272         /// </summary>
273         public string BeforeChangeContent { get; set; }
274
275         /// <summary>
276         /// 修改后内容(针对建设图时,存储建设图ID)
277         /// </summary>
278         public string AfterChangeContent { get; set; }
279
280         /// <summary>
281         /// 描述
282         /// </summary>
283         public string Description { get; set; }
284     }
285 }

Common.ComparisonField 完整方法

示例代码下载:

ComparisonFieldTest.zip

时间: 2024-10-26 04:12:14

C# 两个Object比较的相关文章

JS学习之--比较两个Object数组是否相等

一.问题 在js中是不能直接用“==”或者“===”来计算两个数组是否相等的,那么就需要对数组的值进行比较: 二.次解决方案 对于比较两个数组次要的方法有如下几种,为什么说是次要解决方案呢?因为它不能真正称之为对两个数组的对比. 1. 把两个数组转化为字符串的形式比较,如下: a. 当两个数组元素类型相同,顺序相同时,直接判断是否相等,结果不相等:转化为字符串后,结果相等: var a=[1, 2, 3, 4]; var b = a.slice(); console.log(a); consol

JDK核心JAVA源码解析(1) - Object

想写这个系列很久了,对自己也是个总结与提高.原来在学JAVA时,那些JAVA入门书籍会告诉你一些规律还有法则,但是用的时候我们一般很难想起来,因为我们用的少并且不知道为什么.知其所以然方能印象深刻并学以致用. 首先我们从所有类的父类Object开始: 1. Object类 (1)hashCode方法和equals方法 public native int hashCode(); public boolean equals(Object obj) { return (this == obj); }

javascript引用类型之对象Object

[前面的话] 引用类型:在javascript中,引用类型是一种数据结构,用于将数据和功能组织在一起,它也常被称为类.引用类型有时也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法. 引用对象的值(对象):是引用类型的一个实例.对象是某个特定引用类型的实例,新对象是使用new操作符后跟一个构造函数来创建的.构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的.对象的别名是集合. Object:是一组数据和功能的集合 [1]对象创建:两种Object类型的创建方法 [1.

在Salesforce中为Object创建Master-Detail(Child-Relationship)关联关系

在Salesforce中可以将两个Object建立起一对多的关联关系,本篇文章就简单的叙述一下将两个Object(EricSunObj & EricSunObjC)设置成Master-Detail (1:n)的关联关系,具体的详细步骤如下所示 1):从对应关系Master-Detail中的Detail入手,找到EricSunObjC的详细信息,如下图示,点击下图中的New按钮来创建一个Custom Field 2):指定此Field为Master-Detail Relationship类型(当然

JDK核心JAVA源代码解析(1) - Object

想写这个系列非常久了.对自己也是个总结与提高.原来在学JAVA时.那些JAVA入门书籍会告诉你一些规律还有法则,可是用的时候我们一般非常难想起来,由于我们用的少而且不知道为什么.知其所以然方能印象深刻并学以致用. 首先我们从所有类的父类Object開始: 1. Object类 (1)hashCode方法和equals方法 public native int hashCode(); public boolean equals(Object obj) { return (this == obj);

沫沫金:Java快速合并两个数组【绝技】

需求: 合并两个Object[] a 和Object[] b: 方案 List<Object[]> quotas = new ArrayList<Object[]>(); Object[] objs1 = quotas_1.get(i); Object[] objs2 =quotas_2.get(i); //合并多sheet页数据,切割行级合并 List list = new ArrayList(Arrays.asList(objs1)); list.addAll(Arrays.a

salesforce 零基础学习(六十三)Comparable实现Object列表数据的自定义排序

项目中通常有些需求为需要将某个sObject的数据列表按照某种规则排序显示到前台页面上,但是list上面的sort远远满足不了复杂的功能,此种情况需要自定义比较两个object大小的方法,所以需要创建Compare相关的类实现Comparable接口. 需求:实现Goods__c列表排序,GoodsBrand__c为华为的按照价格升序排序,GoodsBrand__c为联想的按照价格降序排列. 1 public without sharing class ComparedGoods impleme

如何在Node.js中合并两个复杂对象

通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: var obj1 = { "name" : "myname", "status" : 0, "profile": { "sex":"m", "isactive" : tr

JavaScript中的两个等号(==)和三个等号(===)

"Determining whether two variables are equivalent is one of the most important operations in programming." (确定两个变量是否相等是编程中最重要的操作之一)--Nicholas Zakas JavaScript中作比较有两个方式:严格模式(strict comparison 使用三个等号 ===)和概要模式(abstract comparison 使用两个等号 ==),对于他们的意