2

I'm looking for a way to find the difference between the values of properties between two objects of the same type.

I've been working from the example in this stack overflow question:

Finding property differences between two C# objects

This is what I have so far:

public static string Compaire<T>(T initial, T final)
{
    Type currentType = initial.GetType();
    PropertyInfo[] props = currentType.GetProperties();
    StringBuilder sb = new StringBuilder();

    foreach (var prop in props)
    {

        Type equatable = prop.PropertyType.GetInterface("System.IEquatable");

        if (equatable != null)
        {
            var i = prop.GetValue(initial);
            var f = prop.GetValue(final);

            if (i!= null && f != null && !i.Equals(f))
            {
                sb.Append(String.Format(_"{0}.{1} has changed from {2} to {3}. ", currentType.BaseType.Name, prop.Name, i, f));
            }
        }

    }
    return sb.ToString();
}

This is working for most cases however, nullable properties (like Nullable int for example) are not getting compared because (I think) they are not being unboxed and nullable isn't implemented with IEquatable.

Using this method of reflection, is it possible to compare nullables while still avoiding entities that have been disposed (e.g. "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection")?

3
  • I'm sure there's something floating around NuGet. FluentAssertions has object comparison, not sure how deep it goes. Commented Mar 23, 2015 at 21:04
  • I've not heard of that project. I will test it out. Thanks! Commented Mar 23, 2015 at 21:07
  • It's more of a helper library for unit testing, but just google around a little. There should be something. Commented Mar 23, 2015 at 21:10

2 Answers 2

4

Maybe this project can fit your needs: CompareNetObjects

Sign up to request clarification or add additional context in comments.

Comments

1

You could use object.Equals(i,f) and omit the check for IEquatable. If it is neccessary but you would like to include nullables you could include them the following way:

        if (prop.PropertyType.IsGenericType)
        {
            if (prop.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                Type typeParameter = prop.PropertyType.GetGenericArguments()[0];

                var i = prop.GetValue(initial);
                var f = prop.GetValue(final);  
                if(object.Equals(i,f))
                {
                    //...
                }
            }
        }

So you check explicitly for Nullables. The first line checks if the type is generic (true for Nullable List etc.) The second gets the underlying generic type (Nullable<>, List<>) and compares it with the Nullable<> type. The third line gets the first (and in case of Nullable<> only) parameter, just for the case you are interested in what type the Nullable is. So you will get int for Nullable. It is not needed in the code I written, but perhaps you are interested in it. Then the values of both properties are read and compared.

3 Comments

Hi, thanks for your response! None of the properties are of generic type however, following your example I did: 'prop.PropertyType.Equals(typeof(Nullable<>))' and that will catch types of nullable <> but not of nullable <int>, is that possible?
Oh. Sorry. I corrected the code. Intellisense has fooled me.
Thanks for your help, I've marked this as correct. I can't vote up the response because my rep isn't high enough.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.