0%

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

上篇文章《C#之相等比较(常规比较)》写了C#中比较是否相等的常规方法的使用说明,但是在实际开发中,往往也会用到两个引用类型的对象进行比较,而引用类型中有包含引用类型的属性或字段。
例如: 有一个引用类型TestClass,TestClass中同时包含值类型(int)的属性和引用类型属性(ExClass),引用类型的属性中又包含了引用类型的属性(ExClass2)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

1
2
3
4
5
6
7
8
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所有属性值是否相等,包括属性值的属性值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/// <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
{
var b = CompareProperties(po.GetValue(obj1), po.GetValue(obj2), po.PropertyType);
if(!b) return false;
}
}

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中)