Compare 2 objects of the same class
I recently ran into the problem of comparing 2 objects of the same class in C #. I need to know which fields / properties have changed.
Here's an example:
SampleClass
{
string sampleField1;
int sampleField2;
CustomClass sampleField3;
}
And I have 2 SampleClass
object, object1
and object2
for example. These 2 objects have a different field value.
-
Can anyone know a better approach to find out which fields are different?
-
And how do I get the (string) names of these different fields / properties?
- I've heard about Reflection in .Net. Is this the best approach in this situation?
- And if we didn't have a CustomClass field? (I'm just doing this field for a more general approach, this field doesn't exist in my case)
source to share
If you want a general way to get all changed properties
you can use this method (and it uses reflection ^ _ ^)
public List<string> GetChangedProperties(object obj1, object obj2)
{
List<string> result = new List<string>();
if(obj1 == null || obj2 == null )
// just return empty result
return result;
if (obj1.GetType() != obj2.GetType())
throw new InvalidOperationException("Two objects should be from the same type");
Type objectType = obj1.GetType();
// check if the objects are primitive types
if (objectType.IsPrimitive || objectType == typeof(Decimal) || objectType == typeof(String) )
{
// here we shouldn't get properties because its just primitive :)
if (!object.Equals(obj1, obj2))
result.Add("Value");
return result;
}
var properties = objectType.GetProperties();
foreach (var property in properties)
{
if (!object.Equals(property.GetValue(obj1), property.GetValue(obj2)))
{
result.Add(property.Name);
}
}
return result;
}
Note that this method only gets the properties of the primitive type that have changed and the properties of the reference type refer to the same instance
EDIT: Added a check if obj1
or obj2
is a primitive type (int, string ...) because I tried to pass a string object and it will give an error also fixed the error of checking if two values ββareequal
source to share
Slight modification of another answer posted here, but this one works on properties that are not types string
, does not use an internal list, and does some kind of pre-type checking automatically:
public IEnumerable<string> ChangedFields<T>(T first, T second)
{
if (obj1.GetType() != obj2.GetType())
throw new ArgumentOutOfRangeException("Objects should be of the same type");
var properties = first
.GetType()
.GetProperties();
foreach (var property in properties)
{
if(!object.Equals(property.GetValue(first), property.GetValue(second)))
{
yield return property.Name;
}
}
}
source to share
If you need to compare two objects as part of your business logic, then reflection is the way to go, unless of course you can write comparator classes for each type.
If you want to compare two objects at runtime while debugging, there is a neat plugin called Oz Code that can do it for you, something like this:
source to share