C#比較兩個對象是否相等(深度比較)

上篇文章《C#之相等比較(常規比較)》寫了C#中比較是否相等的常規方法的使用說明,但是在實際開發中,往往也會用到兩個引用類型的對象進行比較,而引用類型中有包含引用類型的屬性或字段。
例如: 有一個引用類型TestClass,TestClass中同時包含值類型(int)的屬性和引用類型屬性(ExClass),引用類型的屬性中又包含了引用類型的屬性(ExClass2)。

    public class TestClass
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public ExClass OtherCalss { get; set; }
    }

    public class ExClass
    {
        public string Param1 { get; set; }
        public ExClass2 OtherCalss2 { get; set; }
    }

    public class ExClass2
    {
        public string P1 { get; set; }
        public string P2 { get; set; }
    }

這個時候,如果有兩個TestClass的實例,c1 ,c2

static void Main(string[] args)
{
    TestClass c1 = new TestClass();
    TestClass c2 = new TestClass();
    //TODO:c1.ID=?   c1.Name=?   c1.OtherClass = ?……
    //TODO:c2.ID=?   c2.Name=?   c2.OtherClass = ?……
    //問題: c1的各屬性值是否等於c2的各屬性值
}

假設:c1,c2各自經過不同的操作進行了賦值,現在怎麼比較c1和c2包含的屬性值是否相等???

以上問題是C#提供的常規方法實現不了的(如果有,請各位大牛留言告知,感激不盡……

因此,我就想辦法自己寫了一個比較的方法,稱之爲“深度比較”,就是比較c1和c2所有屬性值是否相等,包括屬性值的屬性值

        /// <summary>
        /// 判斷兩個相同引用類型的對象的屬性值是否相等
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj1">對象1</param>
        /// <param name="obj2">對象2</param>
        /// <param name="type">按type類型中的屬性進行比較</param>
        /// <returns></returns>
        public static bool CompareProperties<T>(T obj1, T obj2, Type type)
        {
            //爲空判斷
            if (obj1 == null && obj2 == null)
                return true;
            else if (obj1 == null || obj2 == null)
                return false;

            Type t = type;
            PropertyInfo[] props = t.GetProperties();
            foreach (var po in props)
            {
                if (IsCanCompare(po.PropertyType))
                {
                    if (!po.GetValue(obj1).Equals(po.GetValue(obj2)))
                    {
                        return false;
                    }
                }
                else
                {
                    return CompareProperties(po.GetValue(obj1), po.GetValue(obj2), po.PropertyType);
                }
            }

            return true;
        }

        /// <summary>
        /// 該類型是否可直接進行值的比較
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        private static bool IsCanCompare(Type t)
        {
            if (t.IsValueType)
            {
                return true;
            }
            else
            {
                //String是特殊的引用類型,它可以直接進行值的比較
                if (t.FullName == typeof(String).FullName)
                {
                    return true;
                }
                return false;
            }
        }

除了屬性值的比較,還可以比較字段值是否相等,原理相同,完整的測試代碼在git上有,
地址:https://github.com/PandaCuipp/ObjectCompares

另外:網上有一種方法,是將c1、c2分別 二進制序列化後比較md5值,不知是否可行,還未試驗(已驗證,代碼已更新到上面的git中)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章