Use a delegate for the equality comparer for LINQ's Distinct()

后端 未结 4 797
梦毁少年i
梦毁少年i 2020-12-02 12:50

I have a LINQ Distinct() statement that uses my own custom comparer, like this:

class MyComparer : IEqualityComparer where T : MyType
{
            


        
4条回答
  •  日久生厌
    2020-12-02 13:49

    Distinct takes an IEqualityComparer as the second argument, so you will need an IEqualityComparer. It's not too hard to make a generic one that will take a delegate, though. Of course, this has probably already been implemented in some places, such as MoreLINQ suggested in one of the other answers.

    You could implement it something like this:

    public static class Compare
    {
        public static IEnumerable DistinctBy(this IEnumerable source, Func identitySelector)
        {
            return source.Distinct(Compare.By(identitySelector));
        }
    
        public static IEqualityComparer By(Func identitySelector)
        {
            return new DelegateComparer(identitySelector);
        }
    
        private class DelegateComparer : IEqualityComparer
        {
            private readonly Func identitySelector;
    
            public DelegateComparer(Func identitySelector)
            {
                this.identitySelector = identitySelector;
            }
    
            public bool Equals(T x, T y)
            {
                return Equals(identitySelector(x), identitySelector(y));
            }
    
            public int GetHashCode(T obj)
            {
                return identitySelector(obj).GetHashCode();
            }
        }
    }
    

    Which gives you the syntax:

    source.DistinctBy(a => a.Id);
    

    Or, if you feel it's clearer this way:

    source.Distinct(Compare.By(a => a.Id));
    

提交回复
热议问题