When looking at Microsoft's implementation of various C# LINQ methods, I noticed that the public extension methods are mere wrappers that return the actual implementation in the form of a separate iterator function.
For example (from System.Linq.Enumerable.cs):
public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
if (first == null) throw Error.ArgumentNull("first");
if (second == null) throw Error.ArgumentNull("second");
return ConcatIterator<TSource>(first, second);
}
static IEnumerable<TSource> ConcatIterator<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second) {
foreach (TSource element in first) yield return element;
foreach (TSource element in second) yield return element;
}
What is the reason for wrapping the iterator like that instead of combining them into one and return the iterator directly?
Like this:
public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second) {
if (first == null) throw Error.ArgumentNull("first");
if (second == null) throw Error.ArgumentNull("second");
foreach (TSource element in first) yield return element;
foreach (TSource element in second) yield return element;
}
Wrappers are used to check method arguments immediately (i.e. when you call LINQ extension method). Otherwise arguments will not be checked until you start to consume iterator (i.e. use query in foreach loop or call some extension method which executes query - ToList, Count etc). This approach is used for all extension methods with deferred type of execution.
If you will use approach without wrapper then:
int[] first = { 1, 2, 3 };
int[] second = null;
var all = first.Concat(second); // note that query is not executed yet
// some other code
...
var name = Console.ReadLine();
Console.WriteLine($"Hello, {name}, we have {all.Count()} items!"); // boom! exception here
With argument-checking wrapper method you will get exception at first.Concat(second)
line.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With