在比较两个对象是否完全相同时,对于string, int等其他value object,可以直接通过“==”或者“Equals”来进行判断。但是对于复杂类,如下的Student类,则需要比较每个属性的值是否相同。并且在Student类中还涉及到了列表的对比问题。

public class Student
{
public string Name { get; set; }
public List<Address> Addresses { get; set; }
public Parent Parent { get; set; }
} public class Address
{
public string Country { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string District { get; set; }
public int Number { get; set; }
} public class Parent
{
public string Mom { get; set; }
public string Dad { get; set; }
}

为了不需要对属性进行一个个的对比,参考网上的各种博客,写了下面的一段代码。(个人感觉这个方法肯定不是最好的,而且解决的问题有限,希望大家能告诉我更好的方法,谢谢。)

static bool CheckEqual<T>(T first, T second, Type type)
{
if (first == null && second == null)
return true;
else if (first == null || second == null)
return false; // 利用反射获取类型的全部属性
PropertyInfo[] properties = type.GetProperties(); foreach(var property in properties)
{
// 首先判断该属性是否为值对象,即int,double,以及string类
if (CheckValueObject(property.PropertyType))
{
// 属性属于值对象和string类的话,则直接使用Equals对两个值进行比较
if (!property.GetValue(first).Equals(property.GetValue(second)))
{
Console.WriteLine(type.Name + "." + property.PropertyType.Name + " is different");
return false;
}
}
else
{
// 属性不属于值对象和string类,且属性是列表。这里已知列表是Address类型的列表
if (property.PropertyType.ToString().Contains("List"))
{
List<Address> item1 = (List<Address>)property.GetValue(first);
List<Address> item2 = (List<Address>)property.GetValue(second);
// 对列表进行比较
if (!CheckListEqual(item1, item2))
{
Console.WriteLine("Addresses are different");
return false;
}
}
else
{
// 属性不属于值对象且不是列表,则递归
return CheckEqual(property.GetValue(first), property.GetValue(second),property.PropertyType);
}
}
}
return true;
} static bool CheckValueObject(Type t)
{
if (t.IsValueType)
return true;
else if (t.FullName == typeof(String).FullName)
return true;
else
return false;
} // 关于列表的对比。
static bool CheckListEqual(List<Address>first, List<Address> second)
{
if (first == null && second == null)
return true;
else if (first == null || second == null)
return false;
// 首先判断两个列表的长度
else if (first.Count != second.Count)
return false;
else
{
// 先将两个列表按照Country属性进行排序
List<Address> _first = first.OrderBy(x => x.Country).ToList();
List<Address> _second = second.OrderBy(x => x.Country).ToList();
// 逐一比较每个元素,如果有不一样的,则返回false
for (int i = 0; i < _first.Count; i++)
{
if(!CheckEqual(_first[i],_second[i], typeof(Address)))
{
return false;
}
}
return true;
} }

Test:

static void Main(string[] args)
{
Address address1 = new Address()
{
Country = "China",
Province = "Guangdong",
City = "Shenzhen",
District = "Nanshan",
Number = 1
};
Address address2 = new Address()
{
Country = "China",
Province = "Guangdong",
City = "Shenzhen",
District = "Nanshan",
Number = 2
};
Address address3 = new Address()
{
Country = "China",
Province = "Guangdong",
City = "Guangzhou",
District = "Huadu",
Number = 1
}; Parent parent1 = new Parent()
{
Mom = "Lily",
Dad = "Tom"
};
Parent parent2 = new Parent()
{
Mom = "Lucy",
Dad = "Jack"
};
Student student1 = new Student()
{
Name = "Spencer",
Parent = parent1,
Addresses = new List<Address>() { address1, address2 }
}; Student student2 = new Student()
{
Name = "Spencer",
Parent = parent1,
Addresses = new List<Address>() { address1, address3 }
}; Student student3 = new Student()
{
Name = "Spencer",
Parent = parent1,
Addresses = new List<Address>() { address1, address3 }
}; Student student4 = new Student()
{
Name = "Spencer",
Parent = parent2,
Addresses = new List<Address>() { address1, address2 }
}; Console.WriteLine(CheckEqual(student1, student4, typeof(Student))); Console.Read();
}

C# 复杂类实例的相等判断的更多相关文章

  1. Struts2 源码分析——Result类实例

    本章简言 上一章笔者讲到关于DefaultActionInvocation类执行action的相关知识.我们清楚的知道在执行action类实例之后会相关处理返回的结果.而这章笔者将对处理结果相关的内容 ...

  2. 简单实用的PHP防注入类实例

    这篇文章主要介绍了简单实用的PHP防注入类实例,以两个简单的防注入类为例介绍了PHP防注入的原理与技巧,对网站安全建设来说非常具有实用价值,需要的朋友可以参考下   本文实例讲述了简单实用的PHP防注 ...

  3. 分享自己用的php分页类实例源码

    分享一个我自己用着的php分页类实例源码,供大家参考,具体内容如下: <?php /** file: page.class.php 完美分页类 Page */ class Page { priv ...

  4. 利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理

    利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理   2018-3-10 15:18 | 发布:Admin | 分类:代码库 | 评论: ...

  5. dagger2系列之生成类实例

    上一节的最后,我讲到一次注入生成类实例的生成步骤.先来回顾一下: 1  Module中存在创建方法,则看此创建方法有没有参数 如果有参数,这些参数也是由Component提供的,返回步骤1逐一生成参数 ...

  6. 自己动手之使用反射和泛型,动态读取XML创建类实例并赋值

    前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能 ...

  7. [No000085]C#反射Demo,通过类名(String)创建类实例,通过方法名(String)调用方法

    using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...

  8. python之元编程(元类实例)

    本实例是元类实例,功能是记录该的子类的类名,并以树状结构展示子类的类名. RegisterClasses继承自type,提供的功能是在__init__接口,为类创建了childrens的集合,并类名保 ...

  9. 转:c++类实例在内存中的分配

    转自:http://blog.csdn.net/alexwei2009/article/details/6157926 c++是一种面向对象的编程语言,它向下保持了对c的兼容,同时也允许程序员能够自由 ...

随机推荐

  1. Android开发-主要的dialog

    dialog是弹出式窗口,点击后会以窗口的形式弹出 主要有添加备注,日历选择等,通过设置事件监听,将dialog弹出来 package com.example.Utils.fragment; impo ...

  2. docker常用命令、镜像命令、容器命令、数据卷,使用dockerFile创建镜像,dockefile的语法规则。

    一.docker常用命令? 1. 常用帮助命令 1.1 docker的信息以及版本号 /* docker info 查看docker的信息 images2 docker本身就是一个镜像. docker ...

  3. 对线面试官,凭借nginx能一战封神吗?

    面试官:小伙子,你对nginx熟悉吗? 我:当然熟悉了,请听我慢慢道来. 心里想,我能吊打面试官吗?今天非得灭一灭面试官的威风,平时都被怼的狗血淋头. 面试官:就你那点花花肠子,咱还不清楚. 我:.. ...

  4. [免费下载应用]iNeuKernel.Ocr 图像数据识别与采集原理和产品化应用

    目       录 1..... 应用概述... 2 2..... 免费下载试用... 2 3..... 视频介绍... 2 4..... iNeuLink.Ocr图像数据采集应用... 2 5... ...

  5. storyboard文件的认识

    - 作用:描述软件界面 - 程序启动的简单过程     - 程序一启动,就会加载`Main.storyboard`文件     - 会创建箭头所指的控制器,并且显示控制器所管理的软件界面 - 配置程序 ...

  6. Java线程--Callable使用

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871727.html Java线程--Callable使用 Callable和Runnabl ...

  7. Velocity学习

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11790482.html Velocity学习: 1. velocity对大小写敏感 2. ve ...

  8. 实现“手机qq”侧滑菜单 -- 吴欧

    基本数据采集 经过体验,手机QQ采用的应该是线性动画,即视图缩放比例等随手指在屏幕上滑动的距离以一次方程的形式变化. 提取基本数据,向右侧滑达到最大幅度时: 1.   右侧主视图左边界距离屏幕左边界的 ...

  9. action标签中method={1}怎么理解

    其实用到method={数字}的时候,相应的前面的action是要出现*通配符来搭配的.比如一个小例子:<action name="user_*" class="U ...

  10. pytest-html 测试报告

    前言 上一篇文章pytest简介中,执行测试用例后,在 pycharm 控制台(方式一)或 Terminal(方式二)中可以查看测试结果.但是在实际的接口自动化项目中一般需要生成直观的测试报告,这个测 ...