0

I am trying to create a generic method, which takes two object as parameters and compares every property within the objects and return the differences. Now I am implementing this using reflection and this works fine for the simple properties(int, string....).

But when it comes to complex data types like a list, array etc. I need to track the number of elements in those lists added or removed. I am trying to figure out the same using below code but am kind of stuck for complex types.

In for each loop its gives me newItem and OldItem of object type. Not able perform other operations.

I need to some solution to find the added and removed items from IEnumerable type properties.

Any suggestions to proceed are appreciated.

Thanks!!

 private static string GenerateAuditLogMessage<T>(T oldObject, T newObject)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        foreach (PropertyInfo pi in properties)
        {
            object oldValue = pi.GetValue(oldObject), newValue = pi.GetValue(newObject);

            if (pi.PropertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(pi.PropertyType))
            {
                Type type = oldValue.GetType().GetGenericArguments()[0];
                foreach (var oldItem in (IEnumerable)oldValue)
                {
                    foreach (var newItem in (IEnumerable)newValue)
                    {
                        var propertyResult = GenerateAuditLogMessage<object>(oldObject, newObject);
                        if (string.IsNullOrEmpty(propertyResult))
                        {
                            // newItem. 
                        }
                    }
                }
                /* Need something like below commented line.*/
                // var added = newValue.Except(oldValue)
                // var removed = oldValue.Except(newValue);
            }
            else
            {
                if (!object.Equals(oldValue, newValue))
                {
                    //....
                }
            }
        }

        return string.Empty;
    }
nitish
  • 81
  • 1
  • 7

1 Answers1

0

This is one thing the old pre-generic System.Collections.* interfaces are still used for: Using reflection on generic collections.

You can cast any generic System.Collections.Generic.IEnumerable<T> to System.Collections.IEnumerable, any System.Collections.Generic.IList<T> to System.Collections.IList, etc. Then you can loop through them in any way they support.

You're already calling o.GetType().GetGenericArguments() to make sure they're collections of the same type, and if they are, you can get the objects in the collections via the non-generic collection interfaces. Once you've got the objects, of course, just recurse.