Skip to main content
deleted 1 character in body
Source Link
user73941
user73941

As slepic in his comment, I also wonder why you use andan enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss (if any) in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.


As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss (if any) in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.


As slepic in his comment, I also wonder why you use an enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss (if any) in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.

added 9 characters in body
Source Link
user73941
user73941

As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss (if any) in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.


As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.


As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss (if any) in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.

added 208 characters in body
Source Link
user73941
user73941

As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.


As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

As slepic in his comment, I also wonder why you use and enumerator in the first and foreach in the second place?


You can eliminate null checks in the versions that call other overrides:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) =>
        source?.DistinctCount((IEqualityComparer<TSource>)null) ?? throw new ArgumentNullException(nameof(source));

can be reduced to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

And the other to:

public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

Do you really need num? Couldn't you just return set.Count?


By using ToHashSet<T>() directly as show below I only find a minor loss in performance compared to your versions:

  public static class ExtensionsReview
  {
    public static int DistinctCount<TSource>(this IEnumerable<TSource> source) => DistinctCount(source, (IEqualityComparer<TSource>)null);

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      return source.ToHashSet(comparer).Count;
    }

    public static int DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) => DistinctCount(source, predicate, null);

    public static int DistinctCount<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate,
        IEqualityComparer<TSource> comparer)
    {
      if (source is null)
      {
        throw new ArgumentNullException(nameof(source));
      }

      if (predicate is null)
      {
        throw new ArgumentNullException(nameof(predicate));
      }

      return source.Where(predicate).ToHashSet(comparer).Count;

    }
  }

According to your tests, I think you should test reference types (classes) with override of Equals()/GetHashCode() (and implementation of IEquatable<T>) with and without a custom comparer.

deleted 1482 characters in body
Source Link
user73941
user73941
Loading
added 83 characters in body
Source Link
user73941
user73941
Loading
added 83 characters in body
Source Link
user73941
user73941
Loading
deleted 292 characters in body
Source Link
user73941
user73941
Loading
added 1676 characters in body
Source Link
user73941
user73941
Loading
Source Link
user73941
user73941
Loading