Take the 2-minute tour ×

I'm trying to compare two complex objects in C#, and produce a Dictionary containing the differences between the two.

If I have a class like so:

public class Product
    public int Id {get; set;}
    public bool IsWhatever {get; set;}
    public string Something {get; set;}
    public int SomeOtherId {get; set;}

And one instance, thus:

var p = new Product
                        Id = 1,
                        IsWhatever = false,
                        Something = "Pony",
                        SomeOtherId = 5

and another:

var newP = new Product
        Id = 1,
        IsWhatever = true

To get the differences between these, i'm doing stuff that includes this:

var oldProps = p.GetType().GetProperties();
var newProps = newP.GetType().GetProperties();

// snip 
foreach(var newInfo in newProps)
    var oldVal = oldInfo.GetValue(oldVersion, null);
    var newVal = newInfo.GetValue(newVersion,null);

// snip - some ifs & thens & other stuff

and it's this line that's of interest

var newVal = newInfo.GetValue(newVersion,null);

Using the example objects above, this line would give me a default value of 0 for SomeOtherId (same story for bools & DateTimes & whathaveyou).

What i'm looking for is a way to have newProps include only the properties that are explicitly specified in the object, so in the above example, Id and IsWhatever. I've played about with BindingFlags to no avail.

Is this possible? Is there a cleaner/better way to do it, or a tool that's out there to save me the trouble?


share|improve this question
try AutoMapper (free)... –  Yahia Mar 14 '13 at 14:52
There is no way to tell whether a property was explicitly initialized in that way. The CLR simply doesn't keep a track of that. –  MattW Mar 14 '13 at 14:52
As far as I understood your task, you can't do this. You can't differentiate at runtime whether you created object by setting bool to false or whether it was set by default when object was created –  Ilya Ivanov Mar 14 '13 at 14:52
You would neet to track in the constructor which properties were explicitly set, and which were defaulted. –  Pieter Geerkens Mar 14 '13 at 14:54
add comment

3 Answers

There is no flag to tell if you a property was explicitly set. What you could do is declare your properties as nullable types and compare value to null.

share|improve this answer
I should have mentioned that I did think of this, but i'd prefer not to dirty the objects in question with nullables. It could be my only option though. Thanks for the feedback in any case. –  Greg Smith Mar 14 '13 at 15:15
Well, sort of similar to that, but somewhat uglier would be to leave your type as not nullable and compare values to default(T), but in that case IsWhatever = false would come up as not modified. –  Ilia G Mar 14 '13 at 15:20
add comment

If i understand you correctly, this is what microsoft did with the xml wrapping classes, generated with the xsd utility, where you had a XIsSpecified, or something like that, for each property X.

So this is what You can do as well - instead of public int ID{get;set;}, add a private member _id , or whatever you choose to call it, and a boolean property IDSpecified which will be set to true whenever Id's setter is called

share|improve this answer
Interesting - will leave the class declarations somewhat cluttered but might be the best option. Thanks for the suggestion. –  Greg Smith Mar 14 '13 at 15:29
add comment
up vote 0 down vote accepted

I ended up fixing the issue without using reflection (or, not using it in this way at least).

It goes, more or less, like this:

public class Comparable
    private IDictionary<string, object> _cache;

    public Comparable()
        _cache = new Dictionary<string, object>();

    public IDictionary<string, object> Cache { get { return _cache; } }

    protected void Add(string name, object val)
        _cache.Add(name, val);

And the product implementation goes to this:

public class Product : Comparable
    private int _id;
    private bool _isWhatever;
    private string _something;
    private int _someOtherId;

    public int Id {get { return _id; } set{ _id = value; Add("Id", value); } }
    public bool IsWhatever { get { return _isWhatever; } set{ _isWhatever = value; Add("IsWhatever ", value); } }
    public string Something {get { return _something; } set{ _something = value; Add("Something ", value); } }
    public int SomeOtherId {get { return _someOtherId; } set{ _someOtherId = value; Add("SomeOtherId", value); } }

And the comparison is then pretty straightforward

var dic = new Dictionary<string, object>();

foreach(var obj in version1.Cache)
    foreach(var newObj in version2.Cache)
        //snip -- do stuff to check equality

Doesn't hugely dirty the model, and works nicely.

share|improve this answer
add comment

Your Answer


