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
dic.Add(....);
}
}
Doesn't hugely dirty the model, and works nicely.