I also searched the Internet for a solution, but did not find any satisfactory. So, I created a universal EqualityComparerFactory:
using System; using System.Collections.Generic; /// <summary> /// Utility class for creating <see cref="IEqualityComparer{T}"/> instances /// from Lambda expressions. /// </summary> public static class EqualityComparerFactory { /// <summary>Creates the specified <see cref="IEqualityComparer{T}" />.</summary> /// <typeparam name="T">The type to compare.</typeparam> /// <param name="getHashCode">The get hash code delegate.</param> /// <param name="equals">The equals delegate.</param> /// <returns>An instance of <see cref="IEqualityComparer{T}" />.</returns> public static IEqualityComparer<T> Create<T>( Func<T, int> getHashCode, Func<T, T, bool> equals) { if (getHashCode == null) { throw new ArgumentNullException(nameof(getHashCode)); } if (equals == null) { throw new ArgumentNullException(nameof(equals)); } return new Comparer<T>(getHashCode, equals); } private class Comparer<T> : IEqualityComparer<T> { private readonly Func<T, int> _getHashCode; private readonly Func<T, T, bool> _equals; public Comparer(Func<T, int> getHashCode, Func<T, T, bool> equals) { _getHashCode = getHashCode; _equals = equals; } public bool Equals(T x, T y) => _equals(x, y); public int GetHashCode(T obj) => _getHashCode(obj); } }
The idea is that the CreateComparer method takes two arguments: a delegate for GetHashCode (T) and a delegate for Equals (T, T)
Example:
class Person { public int Id { get; set; } public string LastName { get; set; } public string FirstName { get; set; } } class Program { static void Main(string[] args) { var list1 = new List<Person>(new[]{ new Person { Id = 1, FirstName = "Walter", LastName = "White" }, new Person { Id = 2, FirstName = "Jesse", LastName = "Pinkman" }, new Person { Id = 3, FirstName = "Skyler", LastName = "White" }, new Person { Id = 4, FirstName = "Hank", LastName = "Schrader" }, }); var list2 = new List<Person>(new[]{ new Person { Id = 1, FirstName = "Walter", LastName = "White" }, new Person { Id = 4, FirstName = "Hank", LastName = "Schrader" }, }); // We're comparing based on the Id property var comparer = EqualityComparerFactory.Create<Person>( a => a.Id.GetHashCode(), (a, b) => a.Id==b.Id); var intersection = list1.Intersect(list2, comparer).ToList(); } }
AcidJunkie Sep 24 '13 at 14:18 2013-09-24 14:18
source share