Alex Rivera | Logout

Can I use Linq's Except() with a lambda expression comparer?

Asked 2011-06-08T11:05:26.820
43

I know I can call linq's Except and specify a custom IEqualityComparer, but implementing a new Comparer class for each data type seems like an overkill for this purpose. Can I use a lambda expression to provide the equality function, like when I use Where or other LINQ functions?

If I can't, is there an alternative?

Edit
Report

2 Answers

27

Can you not use a .Where with a lambda that filters out your required values?

Example as requested:

    static void Main(string[] args)
    {
        var firstCustomers = new[] { new Customer { Id = 1, Name = "Bob" }, new Customer { Id = 2, Name = "Steve" } };
        var secondCustomers = new[] { new Customer { Id = 2, Name = "Steve" }, new Customer { Id = 3, Name = "John" } };

        var customers = secondCustomers.Where(c => !firstCustomers.Select(fc => fc.Id).Contains(c.Id));
    }

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
answered 2011-06-08T11:10:51.957
7

Here's something simple I whipped up:

public class CustomComparer<TSource, TCompareType> : IEqualityComparer<TSource> where TSource : class 
{
    private readonly Func<TSource, TCompareType> getComparisonObject;
    public CustomComparer(Func<TSource,TCompareType> getComparisonObject)
    {
        if (getComparisonObject == null) throw new ArgumentNullException("getComparisonObject");
        this.getComparisonObject = getComparisonObject;
    } 

    /// <summary>
    /// Determines whether the specified objects are equal.
    /// </summary>
    /// <returns>
    /// true if the specified objects are equal; otherwise, false.
    /// </returns>
    /// <param name="x">The first object of type <paramref name="T"/> to compare.
    ///                 </param><param name="y">The second object of type <paramref name="T"/> to compare.
    ///                 </param>
    public bool Equals(TSource x, TSource y)
    {
        if (x == null)
        {
            return (y == null);
        }
        else if (y == null)
        {
            return false;
        }
        return EqualityComparer<TCompareType>.Default.Equals(getComparisonObject(x), getComparisonObject(y));
    }

    /// <summary>
    /// Returns a hash code for the specified object.
    /// </summary>
    /// <returns>
    /// A hash code for the specified object.
    /// </returns>
    /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.
    ///                 </param><exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.
    ///                 </exception>
    public int GetHashCode(TSource obj)
    {
        return EqualityComparer<TCompareType>.Default.GetHashCode(getComparisonObject(obj));
  
answered 2011-10-06T17:27:43.817

Your Answer