Many custom Enumerable extensions can be implemented in terms of other built-in operations - for example, this trivial convenience method:
public static bool AnyOf<TElement>(this TElement item, IEnumerable<TElement> items) { return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)); }
Now this will make any PLINQ query return to a sequential operation, even if PLINQ also has Any - and is equivalent to simply changing the signature:
public static bool AnyOf<T>(this T item, ParallelQuery<T> items) { return items.Any(a => EqualityComparer<T>.Default.Equals(a, item)); }
But duplication of this type seems dirty to me.
At first, I thought that something like below might work, but of course it is not, because extension methods are static methods, so the decision to call Enumerable.Any , unlike ParallelQuery.Any is executed at the time of compilation based on the signature.
public static bool AnyOf<TElement, TEnumerable>(this TElement item, TEnumerable items) where TEnumerable : class, IEnumerable<TElement> { return items.Any(a => EqualityComparer<TElement>.Default.Equals(a, item)); }
I came to the conclusion that this is impossible without creating a copy of each method with a different signature, but maybe I missed something there. (Come on always with impossible questions!)
Perhaps the best example of an assistant that would benefit from parallelization (obviously, maybe a chain, etc.) is something like this.
public static IEnumerable<string> ToStrings(this IEnumerable<object> ienum) { return ienum.Select(a=> a.ToString()); }
^ Compiler error:
The type 'ParallelQuery<TElement>' cannot be used as type parameter 'TEnumerable' in the generic type or method 'AnyOf<TElement,TEnumerable>(TElement, TEnumerable)'. There is no implicit reference conversion from 'ParallelQuery<TElement>' to 'IEnumerable<TElement>'
It is also worth considering that not all ParallelQuery / Enumerable methods are equivalent, even if they are compiled.