C# 确定未知类型的相等性

C# 确定未知类型的相等性,c#,.net,observablecollection,iequalitycomparer,data-compression,C#,.net,Observablecollection,Iequalitycomparer,Data Compression,我需要检查给定实例是否与集合匹配(两者都是未知类型) 看一看 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");

我需要检查给定实例是否与集合匹配(两者都是未知类型)

看一看

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
保存值
newUnknownTypea()

obj2
保存值
newUnknownTypex()

我需要检查两个物体是否相同


请原谅我。如何检查未知类型的相等性。

好的,我认为这里缺少一些要点

首先,你所说的平等是什么意思

当两个对象具有相同的引用时,它们是否相等? 当他们有相同的共同属性时,他们是平等的吗? 或者什么时候

其次(可能更重要),为什么需要检查不知道的对象是否相等?

如果你甚至不知道对象的类型,那么说它们是相等的又有什么意义呢?你甚至不能使用它们

如果您知道对象的类型,那么您就知道如何比较它们

您添加了场景案例4,当您不知道任何类型时,为什么要比较两个不同类型的对象?

在OOP中,您无法比较不同类型的对象,因为这没有意义,您无法比较苹果和梨

这就是为什么我们通常创建包含不同类型的公共部分的接口,或者我们创建方法来转换另一个对象类型

我在这里给出的解决方案意味着您可以控制对象实现

您可能希望重载Equals()方法(从对象继承)

当您需要比较它们时:

obj1.Equals(obj2);
然而,这带来了对象必须是相同类型的限制,不管是什么类型


注意:此处未实现错误检查,您需要执行此操作…

您可以检查可用于通过反射对对象执行深度比较的。

此代码将按类型和公共字段列表对对象进行比较,而无需恢复。它可以通过添加资源化和属性来改进。当然,这并不是所有情况下的解决方案

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;
}

另一种可能是序列化对象并比较序列化的输出


这可以是二进制或xml,或者其他任何形式。这是非常通用的,您可以使用现成的实用程序影响序列化行为。

那么还可能涉及哪些其他类型?根据前面在另一个问题中的评论,类型是否有任何“隐藏”状态,而不是由字段公开?它能包含一个集合吗?它是否可以包含一个
Random
属性,作为隐藏其状态的类型的示例?它能包含循环引用吗?这通常是不可能的,但是如果您约束所涉及的类型,您可以通过反射来实现。(不过,您确实需要注意循环引用…)在场景#2中,
obj1
obj2
只是字符串,或者它们也是
EmpPerson
类型,但您只知道名称?您确实需要解释如何检查相等性。如果
obj1
仅包含名称,而
obj2
包含相同的名称以及ID和地址,那么它们是否相等?通过“它包含随机属性”是否意味着类型可以包含类型为
System.random
的属性?如果是这样,游戏就结束了-你真的无法比较
随机
实例是否相等。如果你能给出场景的预期结果也会有所帮助-在场景4中,如果
obj1
obj2
具有相同的属性,但它们的类型不同,这算不算他们相等?我正在从服务中获取对象。我不知道,它是什么类型的物体。这就是问题所在。@IRPunch好的,我想你已经为这些对象编写了代码了。那你想要什么?有可能比较两件你不知道是什么的事情吗?看看场景4
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;
}