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; }
    }
Student.cs
复制代码
复制代码
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();
        }
复制代码

 

posted @   南风小斯  阅读(1084)  评论(3编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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吧
点击右上角即可分享
微信分享提示