在比较两个对象是否完全相同时,对于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. 关于BIO NIO和AIO的理解

    转载自 :http://blog.csdn.net/anxpp/article/details/51512200 1.BIO编程 1.1.传统的BIO编程 网络编程的基本模型是C/S模型,即两个进程间 ...

  2. shell $用法

    $0 这个程式的执行名字$n 这个程式的第n个参数值,n=1..9$* 这个程式的所有参数,此选项参数可超过9个.$# 这个程式的参数个数$$ 这个程式的PID(脚本运行的当前进程ID号)$! 执行上 ...

  3. centos7无法访问虚拟机web服务

    第一种: 先看下防火墙状态:firewall-cmd --state 关闭防火墙再试试:systemctl stop firewalld.service 第二种,不想关闭防火墙 放开http服务 fi ...

  4. Shell 脚本进阶,经典用法及其案例

    一.条件选择.判断 1.条件选择if (1)用法格式 if 判断条件 1 ; then 条件为真的分支代码 elif 判断条件 2 ; then 条件为真的分支代码 elif 判断条件 3 ; the ...

  5. 火山引擎MARS-APM Plus x 飞书 |降低线上OOM,提高App性能稳定性

    通过使用火山引擎MARS-APM Plus的memory graph功能,飞书研发团队有效分析定位问题线上case多达30例,线上OOM率降低到了0.8‰,降幅达到60%.大幅提升了用户体验,为飞书的 ...

  6. Vue.js项目的兼容性与部署配置

    一.处理兼容性问题的相关插件: 1> 解决移动端某些版本的浏览器,点击事件有3s延时触发的问题 · 安装 fastclick 依赖包:npm install fastclick --save-d ...

  7. R-B Tree

    1.简介 R-B Tree,全称Red-Black Tree,又称为"红黑树",为一种自平衡二叉查找树(特殊的平衡二叉树,都是在插入和删除操作时通过特定操作保持二叉树的平衡,从而获 ...

  8. 微信小程序之video组件与cover-view组件和cover-image组件灵活应用

    前言:最近忙着赶项目,没时间更博:希望和大家一起学习一起进步. 本人遇到的坑,以及爬出坑的方法:在某个微信小程序项目中,有这样一个需求:在滑块swiper组件和swiper-item组件中嵌套vide ...

  9. hihoCoder挑战赛1 毁灭者问题

    题目链接:http://hihocoder.com/problemset/problem/1034 数据结构题,由于每个魔法单位有着不同的回复速度和上限,所以不能根据吸收时间点进行查询和更新.但是如果 ...

  10. shell——read -u

    转自:https://zhidao.baidu.com/question/357781350.html while read -u3 i && read -u4 j;do echo $ ...