Kar B
Kar B

Reputation: 21

Compare Objects in C# but ignore some properties of the object while comparing

I am trying to compare 2 objects(Previous Object with Current Object) to check the equality. Values in previous object and current object are same but UUID is getting changed in current object. I dont want to compare the property UUID but i want to compare the other property in previous object with current object. I used .equals method in C# but since the UUID is different in the current object it is returning false. Could anyone advise me how can I compare those 2 objects by ignoring the property:UUID using C# or please propose a method to compare 2 object by ignore the UUID property. Thanks.

I also tried using ToHashSet().SetEquals(It will not suit because because i have lot of property in the object)

I used .equals method in C#. I also tried using ToHashSet().SetEquals(It will not suit because because i have lot of property in the object)

Expecting: A C# method will take 2 parameters as previousobject and currentobject. It will ignore the property UUID in the object and compare the remaining properties of those 2 objects.

or a C# linq query that will ignore the property UUID in the object and compare the remaining properties of those 2 objects

Please find the XML.I named it as Previous Object and Current Object

Previous Object

<Company>
<EmployeeDetails>
<Employee>
<UUID>111-111-111</UUID>
<Name>Albert</Name>
<Age>30</Age>
<Designation>Sales Manager</Designation>
</Employee>
<Employee>
<UUID>222-222-222</UUID>
<Name>John</Name>
<Age>35</Age>
<Designation>Production Manager</Designation>
</Employee>
</EmployeeDetails>
<EmployeeDetails>
<Employee>
<UUID>333-333-333</UUID>
<Name>Danny</Name>
<Age>40</Age>
<Designation>Network Engineer</Designation>
</Employee>
<Employee>
<UUID>444-444-444</UUID>
<Name>Marty</Name>
<Age>35</Age>
<Designation>Operations</Designation>
</Employee>
</EmployeeDetails>
</Company>

Current Object

<Company>
<EmployeeDetails>
<Employee>
<UUID>aaa-aaa-aaa</UUID>
<Name>Albert</Name>
<Age>30</Age>
<Designation>Sales Manager</Designation>
</Employee>
<Employee>
<UUID>bbb-bbb-bbb</UUID>
<Name>John</Name>
<Age>35</Age>
<Designation>Production Manager</Designation>
</Employee>
</EmployeeDetails>
<EmployeeDetails>
<Employee>
<UUID>ccc-ccc-ccc</UUID>
<Name>Danny</Name>
<Age>40</Age>
<Designation>Network Engineer</Designation>
</Employee>
<Employee>
<UUID>ddd-ddd-ddd</UUID>
<Name>Marty</Name>
<Age>35</Age>
<Designation>Operations</Designation>
</Employee>
</EmployeeDetails>
</Company>

class employee
{
string uuid;
string name;
int age;
string designation;
}

class EmployeeDetails
{
List<employee> employee;
}

class Company
{
List<EmployeeDetails> EmployeeDetails;
}

Upvotes: 0

Views: 110

Answers (2)

Michał Turczyn
Michał Turczyn

Reputation: 37460

Just use write simple method:

bool AreEmployeesEqual(Employee e1, Employee e2)
    => e1.name == e2.name && e1.age == e2.age && e1.designation == e2.designation;

You could override Equals and GetHashCode for Employee class:

public override bool Equals(object obj)
{
    var item = obj as Employee;

    if (item == null)
    {
        return false;
    }

    return this.name.Equals(item.name) && 
        this.age.Equals(item.age) && 
        this.designation.Equals(item.designation);
}

public override int GetHashCode()
{
    unchecked
    {
        int hash = 17;
        hash = hash * 31 + age.GetHashCode();
        hash = hash * 31 + name.GetHashCode();
        hash = hash * 31 + designation.GetHashCode();
        return hash;
    }
}

References:

Upvotes: 1

Utsav Makwana
Utsav Makwana

Reputation: 54

It is always challenging to compare complex objects like you have. but here is the code for comparing objects with the ignore property list you can pass the "UUID" string to ignore the UUID property and it will not check that property in the object.

public static bool AreEqual<T>(T obj1, T obj2, params string[] propertiesToIgnore)
{
    if (ReferenceEquals(obj1, obj2)) return true;
    if (obj1 == null || obj2 == null) return false;
    if (obj1.GetType() != obj2.GetType()) return false;

    var ignoredProperties = new HashSet<string>(propertiesToIgnore);

    foreach (var property in obj1.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        if (ignoredProperties.Contains(property.Name)) continue;

        var value1 = property.GetValue(obj1);
        var value2 = property.GetValue(obj2);

        if (!AreValuesEqual(value1, value2, propertiesToIgnore)) return false;
    }

    return true;
}

private static bool AreValuesEqual(object value1, object value2, params string[] propertiesToIgnore)
{
    if (ReferenceEquals(value1, value2)) return true;
    if (value1 == null || value2 == null) return false;

    if (value1.GetType() != value2.GetType()) return false;

    if (value1 is IEnumerable && !(value1 is string))
    {
        var collection1 = ((IEnumerable)value1).Cast<object>().ToList();
        var collection2 = ((IEnumerable)value2).Cast<object>().ToList();
        return AreCollectionsEqual(collection1, collection2, propertiesToIgnore);
    }

    return value1.Equals(value2);
}

private static bool AreCollectionsEqual(List<object> collection1, List<object> collection2, params string[] propertiesToIgnore)
{
    if (collection1.Count != collection2.Count) return false;

    for (int i = 0; i < collection1.Count; i++)
    {
        if (!AreEqual(collection1[i], collection2[i], propertiesToIgnore)) return false;
    }

    return true;
}

and here is the link to check the working code, please let me know if this solution works for you.

Upvotes: 1

Related Questions