2011-01-12 3 views
2

Я использую внешнюю библиотеку, которая возвращает массив объектов для старого состояния и текущего состояния объекта (где каждый элемент массива представляет свойства и их значения). До сих пор я придумал:Рекурсивно сравнить два массива объектов

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

Это сравнивает все свойства верхнего уровня. Но я также хочу развернуть некоторые (те, которые отмечены атрибутом CompareComplex) сложных свойств, и сравнить их различия между его свойствами. Я бы предположил, что лучший способ добиться этого - использовать рекурсивную функцию. Я не могу это понять, но я уверен, что решение довольно простое.

Я был бы очень признателен, если бы кто-то мог помочь. Спасибо

+0

может быть дубликат http://stackoverflow.com/questions/1539989/c-implementation-of-deep-recursive-object-comparison-in-net-3-5 – BrokenGlass

+0

Аналогичный вопрос задан ранее, см. http://stackoverflow.com/questions/1539989/c-implementation-of-deep-recursive-object-comparison-in-net-3-5 –

ответ

0

веселит за ваши ответы я сумел придумать в следующий метод:

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; 
} 

Несколько вещей, чтобы отметить:

  1. Сумма свойств в моем исходном массиве объекта не сопоставьте количество элементов в type.GetProperties(). Я не вижу, как я могу сказать, имеет ли объект в массиве объектов атрибут IgnoreLogging, поэтому я сравниваю его с типом.
  2. Свойство ChildLoggingAttribute используется для определения того, когда атрибут является сложным типом.

Если у кого-то есть предложения по поводу того, как я могу улучшить это, я бы очень признателен. Спасибо

2

Ваш код сравнивает только первый элемент!

Лучше:

return oldState.SequenceEquals(state); 

Чтобы сделать "глубоко сравнить" переопределить Equals() метод класса "состояние".

0

подход принять для итерации может быть это:

  • написать код для сравнения как ты для одной пары объектов (oldObject и object)
  • скопировать этот тест в петлю и установить объект на перед запуском кода сравнения

, как:

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); 
} 

Важно, выньте этот оператор возврата, поэтому выполнение выполнения не прекратится после итерации для i == 0 и сохраните результаты в другом объекте.

Смежные вопросы