确定未知类型的相等性

本文关键字:类型 未知 | 更新日期: 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格式,或者其他格式。这是非常通用的,您可以使用开箱即用的实用程序来影响序列化行为。