Friday, September 23, 2016

Generic Comparer for DistinctBy Using Func and IComparer For IEnumerable

During development of many projects, I have been come across to develop IComparer for different reasons and situations. Each time creating new comparer for different classes. Therefore, I have found solution to use single generic Comparer for all the IEnumerable extension which requires IComparer for the class.

I have used DistinctBy Example to go throw the Generic Extension Method.



 public static class Compare
    {
        public static IEnumerable<T> DistinctBy<T, TIdentity>(this IEnumerable<T> source, Func<T, TIdentity> identitySelector)
        {
            return source.Distinct(Compare.By(identitySelector));
        }

        public static IEqualityComparer<TSource> By<TSource, TIdentity>(Func<TSource, TIdentity> identitySelector)
        {
            return new DelegateComparer<TSource, TIdentity>(identitySelector);
        }

        private class DelegateComparer<T, TIdentity> : IEqualityComparer<T>
        {
            private readonly Func<T, TIdentity> identitySelector;

            public DelegateComparer(Func<T, TIdentity> 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();
            }
        }
    }

DistinctBy Extension Method


The function simply creates an extension method for IEnumerable together with Func with input of Type and outputting property of type TIdentity.

Using this way any class can provide the property that needs to be used for comparing and calculating hashcode for that property. However, TIdentity usually will be the unique key for the class object.

IEqualityComparer

This function simply create and object of Comparer passing in the Func delegate. The resulting DelegateComparer will use the Func Delegate to fetch the unique property and compare the unique property and calculate the hashcode.

Usage


public class AClass
{
  public string AProperty {get; set;}
}

public IEnumerable<AClass> DistinctAClass(IEnumerable<AClass> aClassList)
{
    aClassList.DistinctBy(a => a.AProperty);
}


Hope this helps to create unnecessary classes for comparer.

No comments:

Post a Comment