Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace ConsoleApplication1
- {
- /// <summary>
- /// Utility class for comparing complex objects
- /// </summary>
- public static class ComparerUtil
- {
- public static DifferencesResult<T> GetDifferences<T, TKey>(
- IEnumerable<T> originalList,
- IEnumerable<T> changedList,
- Func<T, TKey> keyExtractor)
- {
- DifferencesResult<T> results = new DifferencesResult<T>();
- var keyComparer = new KeyEqualityComparer<T, TKey>(keyExtractor);
- results.Added = changedList.Except(originalList, keyComparer);
- results.Removed = originalList.Except(changedList, keyComparer);
- return results;
- }
- public static DifferencesResult<T> GetDifferences<T, TKey, TDiff>(
- IEnumerable<T> originalList,
- IEnumerable<T> changedList,
- Func<T, TKey> keyExtractor,
- Func<T, TDiff> differenceExtractor)
- {
- DifferencesResult<T> results = new DifferencesResult<T>();
- var keyComparer = new KeyEqualityComparer<T, TKey>(keyExtractor);
- var diffComparer = new KeyEqualityComparer<T, TDiff>(differenceExtractor);
- results.Added = changedList.Except(originalList, keyComparer);
- results.Removed = originalList.Except(changedList, keyComparer);
- results.Changed = changedList.Except(originalList, diffComparer)
- .Except(results.Added, keyComparer)
- .Except(results.Removed, keyComparer);
- return results;
- }
- public class DifferencesResult<T>
- {
- public IEnumerable<T> Added { get; set; }
- public IEnumerable<T> Removed { get; set; }
- public IEnumerable<T> Changed { get; set; }
- public DifferencesResult()
- {
- Added = new T[0];
- Removed = new T[0];
- Changed = new T[0];
- }
- }
- /// <summary>
- /// Generice impl of <see cref="IEqualityComparer"/>
- /// </summary>
- /// <example>
- /// var treeComparer = new KeyEqualityComparer<TreeDefinition, int?>((t) => t.TreeID);
- /// </example>
- /// <typeparam name="T">The type of object comparing</typeparam>
- /// <typeparam name="TKey">The type of key comparing</typeparam>
- class KeyEqualityComparer<T, TKey> : IEqualityComparer<T>
- {
- protected readonly Func<T, TKey> keyExtractor;
- public KeyEqualityComparer(Func<T, TKey> keyExtractor)
- {
- this.keyExtractor = keyExtractor;
- }
- public virtual bool Equals(T x, T y)
- {
- return this.keyExtractor(x).Equals(this.keyExtractor(y));
- }
- public int GetHashCode(T obj)
- {
- return this.keyExtractor(obj).GetHashCode();
- }
- }
- }
- public class ComparerUtilExample
- {
- static void Main(string[] args)
- {
- var list = (new String[] { "Hello", "World", "Apple" })
- .Select((t, i) => new Entity(i + 1, t)).ToList();
- var list2 = (new String[] { "Hello", "World", "Apple" })
- .Select((t, i) => new Entity(i + 1, t)).ToList();
- list2.RemoveAt(0);
- list2.Add(new Entity(10, "Orange"));
- list2[0].Name += " Changed";
- //returns what has been added and removed by comparing keys
- var diffs = ComparerUtil.GetDifferences<Entity, int>(list, list2, (k) => k.Id);
- WriteChanged<Entity>(list, list2, diffs);
- //returns what has been added, removed, and changed by comparing by key func and value func
- var diffsWChanged = ComparerUtil.GetDifferences<Entity, int, string>(list, list2, (k) => k.Id, (v) => v.Name);
- WriteChanged<Entity>(list, list2, diffsWChanged);
- }
- class Entity
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public Entity(int id, string name)
- {
- Id = id;
- Name = name;
- }
- public override string ToString()
- {
- return string.Format("{0}:{1}", Id, Name);
- }
- }
- private static void WriteChanged<T>(List<T> list, List<T> list2, ComparerUtil.DifferencesResult<T> diffs)
- {
- Console.WriteLine("list: " + string.Join(" | ", list));
- Console.WriteLine("list: " + string.Join(" | ", list2));
- Console.WriteLine("Added: " + string.Join(" | ", diffs.Added));
- Console.WriteLine("Removed: " + string.Join(" | ", diffs.Removed));
- Console.WriteLine("Changed: " + string.Join(" | ", diffs.Changed));
- Console.WriteLine();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment