在C#中实现泛型对象比较
本文关键字:对象 比较 泛型 实现 | 更新日期: 2023-09-27 18:29:08
我正在实现通用对象比较方法来比较我的项目中的类实例。在每个类中,我都有一些值类型变量及其关联类的绑定列表。对于值类型变量,我可以使用==
运算符或equal
运算符对其进行比较,但对于bindinglist,我不知道如何将其转换为bindinglist<type of associate class>
来迭代并执行递归。
public bool IsEqual<T>(T obj1, T obj2)
{
PropertyInfo[] prop1 = obj1.GetType().GetProperties();
PropertyInfo[] prop2 = obj2.GetType().GetProperties();
for(int i = 0; i < prop1.Count; i++)
{
if(prop1[i].IsValueType && prop2[i].IsValueType)
{
if(prop1.GetValue(i) != prop2.GetValue(i))
return false
}
else
{
//This is bindinglist of associate class
//I need to cast it to iterate in perform recursion here
}
}
return true
}
那么,当属性是绑定列表时,我如何实现递归呢?
p/S:原谅我糟糕的英语
更新:
经过仔细考虑,我按照Stephen Hewlett先生的建议实施了IEqualtable
。非常感谢你,斯蒂芬·休利特先生。对于那些仍然想使用比较函数的人,我会给你一个我认为有效的方法:
public bool IsEqual(Object obj1, Object obj2)
{
PropertyInfo[] prop1 = obj1.GetType().GetProperties();
PropertyInfo[] prop2 = obj2.GetType().GetProperties();
for(int i = 0; i < prop1.Count; i++)
{
if(prop1[i].IsValueType && prop2[i].IsValueType)
{
if(prop1[i].GetValue(obj1, null) != prop2[i].GetValue(obj2, null))
return false;
}
else if (prop1[i].PropertyType.IsGenericType && prop2[i].PropertyType.IsGenericType) //if property is a generic list
{
//Get actual type of property
Type type = prop1[i].PropertyType;
//Cast property into type
var list1 = Convert.ChangeType(prop1[i].GetValue(obj1, null), type);
var list2 = Convert.ChangeType(prop1[i].GetValue(obj2, null), type);
if (list1.count != list2.count)
return false;
for j as integer = 0 to list1.Count - 1
{
//Recursion here
if (!IsEqual(list1(j), list2(j)))
{
return false;
}
}
}
else //if property is instance of a class
{
Type type = prop1[i].PropertyType;
Object object1 = Convert.ChangeType(prop1[i].GetValue(obj1, null), type);
Object object2 = Convert.ChangeType(prop1[i].GetValue(obj2, null), type);
//Recursion
if(!IsEqual(object1, object2))
{
return false;
}
}
}
return true;
}
我非常非常强烈地建议为所有类实现IEquatable,无论它们有多少,因为对不需要它的东西使用反射通常是个坏主意。C#的一个基本优势是通过使用所有内置的类型特性可以获得类型安全性。通过使用反射,你试图模仿C#和.NET已经为你做了什么,但你可能会出错。
您的方法不需要是泛型的,因为它使用反射,所以有问题的对象无论如何都会作为object
传递给反射方法。添加类型参数没有任何好处。如果没有type参数,您将更容易根据需要强制转换绑定列表。