Skip to content

Instantly share code, notes, and snippets.

@skst
Created June 21, 2024 23:49
Show Gist options
  • Save skst/34aecd88df22bf6423b630ad6cc1a96e to your computer and use it in GitHub Desktop.
Save skst/34aecd88df22bf6423b630ad6cc1a96e to your computer and use it in GitHub Desktop.
Convert a lambda expression to an IEqualityComparer<>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Shared;
/// <summary>
/// Convert a lambda expression to an IEqualityComparer<>.
/// </summary>
/// <remarks>
/// Can also make an extension to hide the use of this class in a LINQ method:
///
/// public static class MyExtensions
/// {
/// public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first,
/// IEnumerable<TSource> second,
/// Func<TSource, TSource, bool> comparer)
/// {
/// return first.Except(second, new LambdaComparer<TSource>(comparer));
/// }
/// }
/// </remarks>
/// <see cref="http://brendan.enrick.com/post/LINQ-Your-Collections-with-IEqualityComparer-and-Lambda-Expressions" />
/// <example>
/// List<MyObject> x = myCollection.Except(otherCollection, new LambdaComparer<MyObject>((x, y) => x.Id == y.Id)).ToList();
/// </example>
/// <typeparam name="T"></typeparam>
internal class LambdaComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> _lambdaComparer; // Equals()
private readonly Func<T, int> _lambdaHash; // GetHashCode()
// Use default GetHashCode()
internal LambdaComparer(Func<T, T, bool> lambdaComparer) :
this(lambdaComparer, obj => obj?.GetHashCode() ?? 0)
{
}
internal LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash)
{
_lambdaComparer = lambdaComparer ?? throw new ArgumentNullException(nameof(lambdaComparer));
_lambdaHash = lambdaHash ?? throw new ArgumentNullException(nameof(lambdaHash));
}
public bool Equals(T x, T y)
{
if (x is null)
{
return (y is null);
}
if (y is null)
{
return false;
}
return _lambdaComparer(x, y);
}
public int GetHashCode(T obj)
{
return _lambdaHash(obj);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment