C# 复杂类实例的相等判断
在比较两个对象是否完全相同时,对于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# 复杂类实例的相等判断的更多相关文章
- Struts2 源码分析——Result类实例
本章简言 上一章笔者讲到关于DefaultActionInvocation类执行action的相关知识.我们清楚的知道在执行action类实例之后会相关处理返回的结果.而这章笔者将对处理结果相关的内容 ...
- 简单实用的PHP防注入类实例
这篇文章主要介绍了简单实用的PHP防注入类实例,以两个简单的防注入类为例介绍了PHP防注入的原理与技巧,对网站安全建设来说非常具有实用价值,需要的朋友可以参考下 本文实例讲述了简单实用的PHP防注 ...
- 分享自己用的php分页类实例源码
分享一个我自己用着的php分页类实例源码,供大家参考,具体内容如下: <?php /** file: page.class.php 完美分页类 Page */ class Page { priv ...
- 利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理
利用反射和泛型把Model对象按行储存进数据库以及按行取出然后转换成Model 类实例 MVC网站通用配置项管理 2018-3-10 15:18 | 发布:Admin | 分类:代码库 | 评论: ...
- dagger2系列之生成类实例
上一节的最后,我讲到一次注入生成类实例的生成步骤.先来回顾一下: 1 Module中存在创建方法,则看此创建方法有没有参数 如果有参数,这些参数也是由Component提供的,返回步骤1逐一生成参数 ...
- 自己动手之使用反射和泛型,动态读取XML创建类实例并赋值
前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能 ...
- [No000085]C#反射Demo,通过类名(String)创建类实例,通过方法名(String)调用方法
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...
- python之元编程(元类实例)
本实例是元类实例,功能是记录该的子类的类名,并以树状结构展示子类的类名. RegisterClasses继承自type,提供的功能是在__init__接口,为类创建了childrens的集合,并类名保 ...
- 转:c++类实例在内存中的分配
转自:http://blog.csdn.net/alexwei2009/article/details/6157926 c++是一种面向对象的编程语言,它向下保持了对c的兼容,同时也允许程序员能够自由 ...
随机推荐
- fidder无法下载证书的最佳解决办法
为什么有的小伙伴安装fidder不好使,手机无法下载证书? 1.安装一定要去官网安装! 一定要去官网安装! 一定要去官网安装!官方网址:https://www.telerik.com/download ...
- 返回值String是文本数据
MyController类中: index.jsp中 修改text前: 改为text后: 还是有乱码是因为使用这个ISO-8859-1编码处理的 MyController中修改注解中属性
- Ldap主从复制搭建
LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写, LDAP协议的特点 读取速度远高于写入速度. 对查询做了优化,读取速度优于普通关系数据 ...
- threejs - src - WebGLProgram是如何组建Shader的?
threejs - src - WebGLProgram是如何组建Shader的? WebGLProgram的构建 WebGLProgram构建的时候需要的参数如下: // \param render ...
- Open虚拟专用网络
目录 一:OpenVPN虚拟网络专用 1.简介: 2.OpenVPN的作用 3.远程访问VPN服务 4.OpenVPN两种类型的VPN体系结构 5.全面解析OpenVPN执行流程 6.Openvpn定 ...
- UVA1619 感觉不错 Feel Good(良好的感觉) 题解
0.题面: 给出正整数n和一个(1 <= n <= 100 000)长度的数列,要求找出一个子区间,使这个子区间的数字和乘上子区间中的最小值最大.输出这个最大值与区间的两个端点. 1.思路 ...
- Vulnhub靶机系列之Acid
Acid 下载地址: https://download.vulnhub.com/acid/Acid.rar https://download.vulnhub.com/acid/Acid.rar ...
- docker 安装遇到404 not find
https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce/repodata/repomd.xml: [Errno 14] HTTPS E ...
- Lesson3——Pandas Series结构
1 什么是Series结构? Series 结构,也称 Series 序列,是 Pandas 常用的数据结构之一,它是一种类似于一维数组的结构,由一组数据值(value)和一组标签组成,其中标签与数据 ...
- Window 共享内存
转载请注明来源:https://www.cnblogs.com/hookjc/ C++使用共享内存实现进程间通信文件映射是一种实现进程间单向或双向通信的机制.它允许两个或多个本地进程间相互通信.为了共 ...