-1

I need to check the given instance is matching with the collection (Both are unknown types).

Have a look

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
}

The Equality Check Method:

public bool CheckEquality(object obj1, object obj2)
{
    // Solution for Determining equality for unknown types
}

For example - consider the Following code: (Only for understanding purpose)

Scenario #1

public class EmpPerson
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
}

obj1 holds the instance new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };

obj2 holds the instance new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };

Scenario #2

obj1 holds the value "John Smith".

obj2 holds the value "John Smith".

Scenario #3

obj1 holds the value "John Smith".

obj2 holds the instance new EmpPerson() { ID = 1, Name = "John", Address = "Los Angeles" };

Scenario #4

obj1 holds the value new UnknownTypeA().

obj2 holds the value new UnknownTypeX().

I need to Check both the objects are identical.

Kindly asssit me. how to check the equality for unknown types.

  • 5
    So what other types might be involved? As per comments earlier in another question, might the type have any "hidden" state, not exposed by fields? Can it contain a collection? Can it contain a `Random` property, as an example of a type which hides its state? Can it contain circular references? This isn't generally possible, but if you constrain the types involved, you could do it with reflection. (You do need to be careful about circular references though...) – Jon Skeet Aug 23 '16 at 06:59
  • @JonSkeet - please give you answer... –  Aug 23 '16 at 07:00
  • 1
    In Scenario #2, are `obj1` and `obj2` simply strings, or are they also of type `EmpPerson` but you only know the name? – Lars Kristensen Aug 23 '16 at 07:00
  • I've asked for clarification - I can't answer without clarification. – Jon Skeet Aug 23 '16 at 07:01
  • @JonSkeet - I added one more Scenario too. –  Aug 23 '16 at 07:02
  • @JonSkeet - it contain a random property, –  Aug 23 '16 at 07:04
  • I suggest that, force obj1 and obj2 implement the same interface. In the interface add an method which return a string that can identify the object. Use that string to compare two objects. – neohope Aug 23 '16 at 07:05
  • Maybe your can check via reflection are they of the same type and call Equals in that case. Otherwise you can make compare as it makes in value types by default - list all public fields, and compare their names, types and values, with recousion if needed. It's not an universal solution, but it will be usefull in most cases. – Anton Aug 23 '16 at 07:06
  • @Anton - in the unknown type, how could I check the equality for the property wise. –  Aug 23 '16 at 07:07
  • @JonSkeet - I added one more Scenario too. –  Aug 23 '16 at 07:08
  • 1
    You really need to explain **_how_** you want to check for equality. If `obj1` only holds the name, while `obj2` holds the same name together with an ID and address, are they then equal? – Lars Kristensen Aug 23 '16 at 07:13
  • @LarsKristensen - I given the Class `EmpPerson` only for understanding purpose. From service, I can consume any unknown data, I need to check both the unknown data are same. For example Scenario #1, I need to check all the properties. –  Aug 23 '16 at 07:17
  • @LarsKristensen - just consider Scenario #4, how could you know the properties ? –  Aug 23 '16 at 07:20
  • 2
    By "it contain a random property" do you mean the types can contain a property of type `System.Random`? If so, it's game over - you really can't compare `Random` instances for equality. – Jon Skeet Aug 23 '16 at 07:24
  • 1
    It would also help if you'd give the expected results for the scenarios - in scenario4, if `obj1` and `obj2` have the same properties, but they're of different types, should that count as them being equal or not? – Jon Skeet Aug 23 '16 at 07:25

4 Answers4

1

OK I think there are some points you are missing here...

First of all, what do you mean by equality ?

Are two objects equal when they hold the same reference ? Are they equal when they have a common property that is the same ? Or when ?

Second (and maybe more important), why do you need to check for equality of objects you don't know ?

If you don't even know the types of your objects, what's the point of saying they're equals ? You cannot even use them...

And if you know the types of your objects, then you know how to compare them.

You added scenario case #4, why do you compare two objects of different types when you don't know any type ?

In OOP, you cannot compare objects of different types, because it doesn't make sense, you can't compare apples and pears...

So that's why we usually create Interfaces that hold the common parts of different types, or that we make methods to transform an object type in another.

The solution I give here, implies that you have control over the objects implementation.

You may want to overload the Equals() method (inherited from 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);
    }
}

And whenever you need to compare them :

obj1.Equals(obj2);

This however brings the restrictions that objects need to be of the same type, whatever the type.

NB : Error checking has not been implemented here, you need to do it...

Martin Verjans
  • 4,675
  • 1
  • 21
  • 48
  • I'm getting the object from the service. I don't know, what type of object it is. That's the problem. –  Aug 23 '16 at 07:13
  • @IRPunch OK I thought you did wrote the code for the objects. Then what do you want ? Is it possible to compare two things that you have no idea of what they are ? – Martin Verjans Aug 23 '16 at 07:15
  • Have a look in Scenario #4 –  Aug 23 '16 at 07:21
1

You could check out the Compare-Net-Objects deep equals library which can be used to perform a deep compare of objects via reflection.

Nico
  • 3,542
  • 24
  • 29
1

this code will compare without recoursion objects by type and by public fields list. It can be improved by adding recoursion, and properties. But it will not be soluton for all cases, of couse.

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;
}
Anton
  • 339
  • 2
  • 15
0

Another possibility is to serialize the objects and compare the serialized output.

Binary serialization for deep object comparison

This can be either binary or xml, or whatever. This is very generic and you can influence the serialization behavior with out-of-the-box utilities.

Community
  • 1
  • 1
fixagon
  • 5,506
  • 22
  • 26