C# 复杂类实例的相等判断
在比较两个对象是否完全相同时,对于string, int等其他value object,可以直接通过“==”或者“Equals”来进行判断。但是对于复杂类,如下的Student类,则需要比较每个属性的值是否相同。并且在Student类中还涉及到了列表的对比问题。如果没有在Student类中重写Equals()方法的话,如何通过反射比较两个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(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧