/// <summary>
 /// Returns source.Distinct(comparer) in a linqified way.
 /// </summary>
 public static IEnumerable <T> DistinctBy <T, TKey>(this IEnumerable <T> source,
                                                    Func <T, TKey> keySelector)
 {
     source.ThrowIfArgumentNull(nameof(source));
     keySelector.ThrowIfArgumentNull(nameof(keySelector));
     return(source.Distinct(
                // calls new GenericEqualityComparer<T, TKey>(keySelector)
                GenericEqualityComparer <T> .By(keySelector)
                ));
 }
 /// <summary>
 /// Returns source.Except(second, comparer) in a linqified way.
 /// </summary>
 public static IEnumerable <T> ExceptBy <T, TKey>(this IEnumerable <T> source, IEnumerable <T> second,
                                                  Func <T, TKey> keySelector)
 {
     source.ThrowIfArgumentNull(nameof(source));
     second.ThrowIfArgumentNull(nameof(second));
     keySelector.ThrowIfArgumentNull(nameof(keySelector));
     return(source.Except(second,
                          // calls new GenericEqualityComparer<T, TKey>(keySelector)
                          GenericEqualityComparer <T> .By(keySelector)
                          ));
 }