2012-05-01 2 views
2

У меня есть 2 списков типа объекта:
Получить различие между два списком

 
List<MyClass> list1;
List<MyClass> list2;

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

+2

HTTP: //msdn.microsoft.com/en-us/library/bb460136.aspx, http://msdn.microsoft.com/en-us/library/bb300779.aspx, http://msdn.microsoft.com/en- us/library/bb397894.aspx –

+7

Что именно вы подразумеваете под «изменением»? Например, если list1 имеет «foO», а list2 имеет «bar», это добавление и удаление или изменение? –

+4

Пожалуйста, представьте ожидаемый ввод и вывод. Ваш вопрос не дает понять, заботитесь ли вы о порядке, в котором происходят объекты, или можете ли вы дублировать объекты в одном списке или как вы определяете, являются ли два объекта одинаковыми, даже если они «изменены». – StriplingWarrior

ответ

12

Попробуйте Except с Union, но вам нужно будет сделать это как для того, чтобы найти различия в обоих.

var exceptions = list1.Except(list2).Union(list2.Except(list1)).ToList(); 

ИЛИ как альтернативу Linq, там может быть гораздо быстрее подход: HashSet.SymmetricExceptWith():

var exceptions = new HashSet(list1); 

exceptions.SymmetricExceptWith(list2); 
+0

+1 для недоиспользуемого 'HashSet'. –

0

Вы можете использовать FindAll, чтобы получить результат, который вы хотите, даже у вас нет IEquatable или IComparable, реализованных в вас r MyClass. Вот один пример:

List<MyClass> interetedList = list1.FindAll(delegate(MyClass item1) { 
    MyClass found = list2.Find(delegate(MyClass item2) { 
    return item2.propertyA == item1.propertyA ...; 
    } 
    return found != null; 
}); 

Таким же образом, вы можете получить ваши заинтересованные детали из list2 путем сравнения list1.

Эта стратегия может также получить ваши «измененные» предметы.

0

Один из способов получить элементы, которые находятся либо в list1 или list2, но не в обоих будет:

var common = list1.Intersect(list2); 
var exceptions = list1.Except(common).Concat(list2.Except(common)); 
0

Попробуйте для сравнения объектов и петля вокруг него для List<T>

public static void GetPropertyChanges<T>(this T oldObj, T newObj) 
{ 
    Type type = typeof(T); 
    foreach (System.Reflection.PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) 
    { 
     object selfValue = type.GetProperty(pi.Name).GetValue(oldObj, null); 
     object toValue = type.GetProperty(pi.Name).GetValue(newObj, null); 
     if (selfValue != null && toValue != null) 
     { 
      if (selfValue.ToString() != toValue.ToString()) 
      { 
      //do your code 
      } 
     } 
    } 
} 
Смежные вопросы