在比较两个对象是否完全相同时,对于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. MySQL数据类型操作(char与varchar)

    目录 一:MySQL数据类型之整型 1.整型 2.验证不同类型的int是否会空出一个存储正负号 3.增加约束条件 去除正负号(unsigned) 二:浮点型 1.浮点型 2.验证浮点型精确度 三:字符 ...

  2. 第08讲:Flink 窗口、时间和水印

    Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 第04讲:Flin ...

  3. numpy常用函数记录

    np.square() 函数返回一个新数组,该数组的元素值为源数组元素的平方. 源阵列保持不变. 示例: import numpy as np a = np.array([[1, 2, 3], [4, ...

  4. Django class meta

    class Main(models.Model): img = models.CharField(max_length=200) # 图片 name = models.CharField(max_le ...

  5. Servlet中的Filter 过滤器的简单使用!

    package com.aaa.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servle ...

  6. 洛谷P5019 [NOIP2018 提高组] 铺设道路

    题目描述 春春是一名道路工程师,负责铺设一条长度为 n 的道路. 铺设道路的主要工作是填平下陷的地表.整段道路可以看作是 n 块首尾相连的区域,一开始,第 i 块区域下陷的深度为 di. 春春每天可以 ...

  7. HTTP消息头(HTTP headers)-HTTP请求头与HTTP响应头

    感谢大佬:https://itbilu.com/other/relate/E1T0q4EIe.html HTTP协议将传输的信息分隔为两部分:HTTP信息头.HTTP信息体.通过HTTP头信息,使客户 ...

  8. 增删改查简单的sql语句

    insert INSERT   INTO    t_stu   (name,age)  VALUES  ('wang',12) INSERT INTO    t_stu   VALUES(NULL,' ...

  9. Linux-标准输入标准输出

    标准输入(代码为0) 标准输出(代码为1) 标准错误输出(代码为2) 将标准输出重定向到一个文件 find /etc -name fileA >list 等同于 find /etc -name ...

  10. 推荐一款仿iPhone桌面的代码. ___王朋.

    Demo:https://files.cnblogs.com/files/sixindev/LxGridView-master.zip 这是作者原来的效果图,很多东西还需要慢慢学习.作者用的很多类,根 ...