确定未知类型的相等性
本文关键字:类型 未知 | 更新日期: 2023-09-27 18:03:37
我需要检查给定的实例是否与集合匹配(两者都是未知类型)。
看一看
void Main()
{
// Employee "John" Object got from Service Layer #1
Object obj1 = Client1.GetObject("John");
// Employee "John" Object got from Service Layer #2
Object obj2 = Client2.GetObject("John");
bool flag = CheckEquality(obj1, obj2); // Both objects are Unknown Type
}
相等性检查方法:
public bool CheckEquality(object obj1, object obj2)
{
// Solution for Determining equality for unknown types
}
例如-考虑以下代码:(仅为理解目的)
场景# 1
public class EmpPerson
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
obj1
持有实例new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };
obj2
持有new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };
场景# 2
obj1
价值"John Smith"
。
obj2
价值"John Smith"
。
场景# 3
obj1
保存值"John Smith"
。
obj2
保存实例new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };
场景# 4
obj1
保存值new UnknownTypeA()
。
obj2
保存值new UnknownTypeX()
。
我需要检查两个对象是否相同。
请帮助我。如何检查未知类型的相等性
您可以查看compare - net - objects深度相等库,该库可用于通过反射执行对象的深度比较。
此代码将按类型和公共字段列表进行无递归比较。可以通过添加递归和属性来改进它。当然,这不是所有情况下的解决方案。
bool AreEquals(object a, object b)
{
if (a == null && b == null) return true;
if (a == null || b == null) return false;
var typeA = a.GetType();
var typeB = b.GetType();
if (typeA.Equals(typeB)) return a.Equals(b);
var fieldsA = typeA.GetFields().Where(field => field.IsPublic).ToArray();
var fieldsB = typeB.GetFields().Where(field => field.IsPublic).ToArray();
if (fieldsA.Length != fieldsB.Length) return false;
foreach(var field in fieldsA)
{
var other = fieldsB.FirstOrDefault(f => f.FieldType.Equals(field.FieldType) && f.Name.Equals(field.Name));
if (other == null) return false;
if (!field.GetValue(a).Equals(other.GetValue(b))) return false;
}
return true;
}
好的,我认为你在这里遗漏了一些要点…
首先,相等是什么意思?
保存相同引用的两个对象是否相等?当它们有相同的共同属性时它们相等吗?
第二(可能也是更重要的),为什么你需要检查你不知道的对象是否相等?
如果你连对象的类型都不知道,说它们相等又有什么意义呢?你甚至不能使用它们…
如果你知道对象的类型,那么你就知道如何比较它们。
您添加了场景#4,为什么在不知道任何类型的情况下比较两个不同类型的对象?
在OOP中,你不能比较不同类型的对象,因为这没有意义,你不能比较苹果和梨…
所以这就是为什么我们通常创建包含不同类型的公共部分的接口,或者我们创建方法来转换另一个对象类型的原因。
我在这里给出的解决方案意味着您可以控制对象的实现。
你可能想重载Equals()方法(继承自Object)。
public class EmpPerson
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public override bool Equals(object obj)
{
EmpPerson cmp = (EmpPerson)obj;
return ID.Equals(cmp.ID);
}
}
当你需要比较它们时:
obj1.Equals(obj2);
然而,这带来了对象必须是相同类型的限制,无论类型是什么
注意:这里没有实现错误检查,您需要这样做…
另一种可能性是序列化对象并比较序列化后的输出。
深度对象比较的二进制序列化
可以是二进制或xml格式,或者其他格式。这是非常通用的,您可以使用开箱即用的实用程序来影响序列化行为。