开发者

Recursively Compare Two Object Arrays

开发者 https://www.devze.com 2023-02-04 08:41 出处:网络
I\'m using an external library which returns an object array for the old state and current state of an object (where each item in the array represents the properties and their values).So far i have co

I'm using an external library which returns an object array for the old state and current state of an object (where each item in the array represents the properties and their values). So far i have come up with:

for (var i = 0; i < oldState.Length; i++) { return oldState[i].Equals(state[i]); }

This compares all the top level propert开发者_JAVA技巧ies. But i also wish to drill into some (ones marked with the attribute CompareComplex) of the complex properties and compare for differences between it's properties them aswell. I'd imagine the best way to achieve this would be to use a recursive function. I can't quite get my head around this but i'm sure the solution is quite simple.

I'd really appreciate it if someone could help. Thanks


Your code compares just the first element!

Better:

return oldState.SequenceEquals(state);

To do a "deep compare" override the Equals() method of the "state" class.


An approach to take for the iteration could be is:

  • write the code for how'd you compare for a single pair of objects (oldObject and object)
  • copy that test into the loop, and set the object at before running the comparison code

like:

for (var i = 0; i < oldState.Length; i++)
{
    ObjectType oldObject = oldState[i];
    ObjectType object= state[i];

    \\insert your comparison code here
    oldObject.Property.Equals(object.Property);
}

Importantly, take out that return statement so execution doesn't stop after the the iteration for i == 0, and keep your results in another object.


cheers for your answers i have managed to come up the the following method:

private bool Compare(Type type, string[] propertyNames, object[] oldState, object[] state) {
    // Get the property indexes to ignore
    var propertyIndexesToIgnore = type.GetProperties()
        .Where(p => p.GetCustomAttributes(typeof(IgnoreLoggingAttribute), false).Count() > 0)
        .Select(p => Array.IndexOf(propertyNames, p.Name)).ToArray();

    // Get the child property indexes
    var childPropertyIndexes = type.GetProperties()
        .Where(p => p.GetCustomAttributes(typeof(ChildLoggingAttribute), false).Count() > 0)
        .Select(p => Array.IndexOf(propertyNames, p.Name)).ToArray();

    for (var i = 0; i < oldState.Length; i++) {
        // If we need to check the child properties
        if (childPropertyIndexes.Contains(i)) {
            if (oldState[i] == null)
                break;

            var childPropertyType = oldState[i].GetType();
            var childProperties = oldState[i].GetType().GetProperties();

            // Recursively call this function to check the child properties
            if (Compare(childPropertyType, childProperties.Select(p => p.Name).ToArray(), childProperties.Select(p => p.GetValue(oldState[i], null)).ToArray<object>(), childProperties.Select(p => p.GetValue(state[i], null)).ToArray<object>()))
                return true;
        } else if (!propertyIndexesToIgnore.Contains(i) && ((oldState[i] != null && state[i] != null && !oldState[i].Equals(state[i])) || (oldState[i] != null && state[i] == null) || (oldState[i] == null && state[i] != null)))
            return true;
    }

    return false;
}

A few things to note:

  1. The amount of properties in my initial object array doesn't match the number of items in type.GetProperties(). I can't see how i can say whether an object within the object array has the IgnoreLogging attribute so i compare it against the type.
  2. The ChildLoggingAttribute is used to determine when an attribute is a complex type.

If anyone has any suggestions on how i can improve this then i'd really appreciate it. Thanks

0

精彩评论

暂无评论...
验证码 换一张
取 消