Reputation: 103
Recently, I ran into a problem of comparing 2 objects of the same class in C#. I need to know which fields/properties are changed.
Here is the example:
SampleClass
{
string sampleField1;
int sampleField2;
CustomClass sampleField3;
}
And I have 2 SampleClass
object, object1
and object2
, for example.
These 2 objects have some different field value.
Can anyone know the best approach to get which fields are different?
And how to get the (string) names of that different fields/properties?
Upvotes: 4
Views: 2723
Reputation: 119186
A slight modification of another answer posted here, but this one works with properties that are not string
types, doesn't use an internal list and does automatic some preliminary type checking as it's generic:
public IEnumerable<string> ChangedFields<T>(T first, T second)
{
if (first.GetType() != second.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;
}
}
}
Upvotes: 3
Reputation: 1697
If you want Generic way to get all changed properties
you can use this method (and it is using 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;
}
Please note that this method only gets Primitive type properties that have changed and reference type properties that refer to the same instance
EDIT: Added validation in case if obj1
or obj2
is primitive type (int,string ... ) because I tried to pass string object and it will give an error
also fixed bug of checking whether the two values are equal
Upvotes: 5
Reputation: 676
If you need to compare two objects as part of your business logic 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 run time during debugging, there is a neat plugin called Oz Code that can do that for you, something like this:
Upvotes: 2