Slepic and Henrik are wondering about the use of `foreach` and enumerator, and I'm too.
 
Anyway, instead of having different versions with actual implementations for the same purpose (count the distinct elements), you can create one private method with the full implementation, and then, just call back this method on the other methods. 

So, the main implementation would be like this : 

    private static int CountDistinctIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate, IEqualityComparer<TSource> comparer)
    {
    	if (source == null) throw new ArgumentNullException(nameof(source));
    
    	var set = new HashSet<TSource>(comparer);
    	var count = 0;
    	foreach (TSource element in source)
    	{
    		checked
    		{
    			if (set.Add(element) && predicate(element))
    			{
    				count++;
    			}
    
    		}
    	}
    
    	return count;
    }


Now, it's a matter of calling back this method with the appropriate arguments. 

Like this : 

    public static int CountDistinct<TSource>(this IEnumerable<TSource> source)
    {
        return CountDistinctIterator<TSource>(source, (s) => true, null);
    }
    
    public static int CountDistinct<TSource>(this IEnumerable<TSource> source,  IEqualityComparer<TSource> comparer)
    {
        return CountDistinctIterator<TSource>(source, (s) => true, comparer);
    }
    
    public static bool AnyDistinct<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
    {
        return CountDistinctIterator<TSource>(source, predicate, null) == 1;
    }
    
    public static bool AnyDistinct<TSource>(this IEnumerable<TSource> source)
    {
        return CountDistinctIterator<TSource>(source, (s) => true, null) == 1;
    }

although, for this `Distinct` I don't see any usage for `Func<TSource, bool> predicate` except for checking if the element exists or not. As the `Distinct` would get the unique elements, and if you say `element == xxx` it'll always return `1` if exists, and `0` if not. Unless there is any other uses except this one, in my opinion, I find it beneficial if rename this method: 

    DistinctCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)

to something meaningful other than `DistinctCount` like for instance `DistinctAny` which return boolean (true if `DistinctCount` returns 1, false if 0). 


**UPDATE :** 
I have changed the methods name from `DistinctCount` to `CountDistinct` the reason of this is because the method is `Counting`, so the Count needs to be first so it would be easier to picked up, the other reason is doing this will make it appear after `Count` on the intellisense list. I also added `AnyDistinct` methods which replaced the mentioned method (the one with `Func<TSource, bool>`).