Refactored the SuperIOHardware class.
1 #region License, Terms and Author(s)
4 // Copyright (c) 2007 Atif Aziz, Joseph Albahari. All rights reserved.
8 // Atif Aziz, http://www.raboof.com
10 // This library is free software; you can redistribute it and/or modify it
11 // under the terms of the New BSD License, a copy of which should have
12 // been delivered along with this distribution.
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 namespace System.Linq {
31 public partial class Enumerable { }
32 public partial interface IGrouping<out TKey, TElement> { }
33 public partial interface ILookup<TKey, TElement> { }
34 public partial interface IOrderedEnumerable<TElement> { }
37 namespace System.Runtime.CompilerServices {
38 public partial class ExtensionAttribute { }
43 // $Id: Enumerable.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
50 using System.Collections;
51 using System.Collections.Generic;
52 using System.Diagnostics;
58 /// Provides a set of static (Shared in Visual Basic) methods for
59 /// querying objects that implement <see cref="IEnumerable{T}" />.
62 static partial class Enumerable
65 /// Returns the input typed as <see cref="IEnumerable{T}"/>.
68 public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
74 /// Returns an empty <see cref="IEnumerable{T}"/> that has the
75 /// specified type argument.
78 public static IEnumerable<TResult> Empty<TResult>()
80 return Sequence<TResult>.Empty;
84 /// Converts the elements of an <see cref="IEnumerable"/> to the
88 public static IEnumerable<TResult> Cast<TResult>(
89 this IEnumerable source)
91 if (source == null) throw new ArgumentNullException("source");
93 return CastYield<TResult>(source);
96 private static IEnumerable<TResult> CastYield<TResult>(
99 foreach (var item in source)
100 yield return (TResult) item;
104 /// Filters the elements of an <see cref="IEnumerable"/> based on a specified type.
107 public static IEnumerable<TResult> OfType<TResult>(
108 this IEnumerable source)
110 if (source == null) throw new ArgumentNullException("source");
112 return OfTypeYield<TResult>(source);
115 private static IEnumerable<TResult> OfTypeYield<TResult>(
118 foreach (var item in source)
120 yield return (TResult) item;
124 /// Generates a sequence of integral numbers within a specified range.
126 /// <param name="start">The value of the first integer in the sequence.</param>
127 /// <param name="count">The number of sequential integers to generate.</param>
129 public static IEnumerable<int> Range(int start, int count)
132 throw new ArgumentOutOfRangeException("count", count, null);
134 var end = (long) start + count;
135 if (end - 1 >= int.MaxValue)
136 throw new ArgumentOutOfRangeException("count", count, null);
138 return RangeYield(start, end);
141 private static IEnumerable<int> RangeYield(int start, long end)
143 for (var i = start; i < end; i++)
148 /// Generates a sequence that contains one repeated value.
151 public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
153 if (count < 0) throw new ArgumentOutOfRangeException("count", count, null);
155 return RepeatYield(element, count);
158 private static IEnumerable<TResult> RepeatYield<TResult>(TResult element, int count)
160 for (var i = 0; i < count; i++)
161 yield return element;
165 /// Filters a sequence of values based on a predicate.
168 public static IEnumerable<TSource> Where<TSource>(
169 this IEnumerable<TSource> source,
170 Func<TSource, bool> predicate)
172 if (predicate == null) throw new ArgumentNullException("predicate");
174 return source.Where((item, i) => predicate(item));
178 /// Filters a sequence of values based on a predicate.
179 /// Each element's index is used in the logic of the predicate function.
182 public static IEnumerable<TSource> Where<TSource>(
183 this IEnumerable<TSource> source,
184 Func<TSource, int, bool> predicate)
186 if (source == null) throw new ArgumentNullException("source");
187 if (predicate == null) throw new ArgumentNullException("predicate");
189 return WhereYield(source, predicate);
192 private static IEnumerable<TSource> WhereYield<TSource>(
193 IEnumerable<TSource> source,
194 Func<TSource, int, bool> predicate)
197 foreach (var item in source)
198 if (predicate(item, i++))
203 /// Projects each element of a sequence into a new form.
206 public static IEnumerable<TResult> Select<TSource, TResult>(
207 this IEnumerable<TSource> source,
208 Func<TSource, TResult> selector)
210 if (selector == null) throw new ArgumentNullException("selector");
212 return source.Select((item, i) => selector(item));
216 /// Projects each element of a sequence into a new form by
217 /// incorporating the element's index.
220 public static IEnumerable<TResult> Select<TSource, TResult>(
221 this IEnumerable<TSource> source,
222 Func<TSource, int, TResult> selector)
224 if (source == null) throw new ArgumentNullException("source");
225 if (selector == null) throw new ArgumentNullException("selector");
227 return SelectYield(source, selector);
230 private static IEnumerable<TResult> SelectYield<TSource, TResult>(
231 IEnumerable<TSource> source,
232 Func<TSource, int, TResult> selector)
235 foreach (var item in source)
236 yield return selector(item, i++);
240 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />
241 /// and flattens the resulting sequences into one sequence.
244 public static IEnumerable<TResult> SelectMany<TSource, TResult>(
245 this IEnumerable<TSource> source,
246 Func<TSource, IEnumerable<TResult>> selector)
248 if (selector == null) throw new ArgumentNullException("selector");
250 return source.SelectMany((item, i) => selector(item));
254 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
255 /// and flattens the resulting sequences into one sequence. The
256 /// index of each source element is used in the projected form of
260 public static IEnumerable<TResult> SelectMany<TSource, TResult>(
261 this IEnumerable<TSource> source,
262 Func<TSource, int, IEnumerable<TResult>> selector)
264 if (selector == null) throw new ArgumentNullException("selector");
266 return source.SelectMany(selector, (item, subitem) => subitem);
270 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
271 /// flattens the resulting sequences into one sequence, and invokes
272 /// a result selector function on each element therein.
275 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
276 this IEnumerable<TSource> source,
277 Func<TSource, IEnumerable<TCollection>> collectionSelector,
278 Func<TSource, TCollection, TResult> resultSelector)
280 if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
282 return source.SelectMany((item, i) => collectionSelector(item), resultSelector);
286 /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
287 /// flattens the resulting sequences into one sequence, and invokes
288 /// a result selector function on each element therein. The index of
289 /// each source element is used in the intermediate projected form
293 public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
294 this IEnumerable<TSource> source,
295 Func<TSource, int, IEnumerable<TCollection>> collectionSelector,
296 Func<TSource, TCollection, TResult> resultSelector)
298 if (source == null) throw new ArgumentNullException("source");
299 if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
300 if (resultSelector == null) throw new ArgumentNullException("resultSelector");
302 return SelectManyYield(source, collectionSelector, resultSelector);
305 private static IEnumerable<TResult> SelectManyYield<TSource, TCollection, TResult>(
306 this IEnumerable<TSource> source,
307 Func<TSource, int, IEnumerable<TCollection>> collectionSelector,
308 Func<TSource, TCollection, TResult> resultSelector)
311 foreach (var item in source)
312 foreach (var subitem in collectionSelector(item, i++))
313 yield return resultSelector(item, subitem);
317 /// Returns elements from a sequence as long as a specified condition is true.
320 public static IEnumerable<TSource> TakeWhile<TSource>(
321 this IEnumerable<TSource> source,
322 Func<TSource, bool> predicate)
324 if (predicate == null) throw new ArgumentNullException("predicate");
326 return source.TakeWhile((item, i) => predicate(item));
330 /// Returns elements from a sequence as long as a specified condition is true.
331 /// The element's index is used in the logic of the predicate function.
334 public static IEnumerable<TSource> TakeWhile<TSource>(
335 this IEnumerable<TSource> source,
336 Func<TSource, int, bool> predicate)
338 if (source == null) throw new ArgumentNullException("source");
339 if (predicate == null) throw new ArgumentNullException("predicate");
341 return TakeWhileYield(source, predicate);
344 private static IEnumerable<TSource> TakeWhileYield<TSource>(
345 this IEnumerable<TSource> source,
346 Func<TSource, int, bool> predicate)
349 foreach (var item in source)
350 if (predicate(item, i++))
357 /// Returns a specified number of contiguous elements from the start
361 public static IEnumerable<TSource> Take<TSource>(
362 this IEnumerable<TSource> source,
365 return source.TakeWhile((item, i) => i < count);
368 private static class Futures<T>
370 public static readonly Func<T> Default = () => default(T);
371 public static readonly Func<T> Undefined = () => { throw new InvalidOperationException(); };
375 /// Base implementation of First operator.
378 private static TSource FirstImpl<TSource>(
379 this IEnumerable<TSource> source,
382 if (source == null) throw new ArgumentNullException("source");
383 Debug.Assert(empty != null);
385 var list = source as IList<TSource>; // optimized case for lists
387 return list.Count > 0 ? list[0] : empty();
389 using (var e = source.GetEnumerator()) // fallback for enumeration
390 return e.MoveNext() ? e.Current : empty();
394 /// Returns the first element of a sequence.
397 public static TSource First<TSource>(
398 this IEnumerable<TSource> source)
400 return source.FirstImpl(Futures<TSource>.Undefined);
404 /// Returns the first element in a sequence that satisfies a specified condition.
407 public static TSource First<TSource>(
408 this IEnumerable<TSource> source,
409 Func<TSource, bool> predicate)
411 return First(source.Where(predicate));
415 /// Returns the first element of a sequence, or a default value if
416 /// the sequence contains no elements.
419 public static TSource FirstOrDefault<TSource>(
420 this IEnumerable<TSource> source)
422 return source.FirstImpl(Futures<TSource>.Default);
426 /// Returns the first element of the sequence that satisfies a
427 /// condition or a default value if no such element is found.
430 public static TSource FirstOrDefault<TSource>(
431 this IEnumerable<TSource> source,
432 Func<TSource, bool> predicate)
434 return FirstOrDefault(source.Where(predicate));
438 /// Base implementation of Last operator.
441 private static TSource LastImpl<TSource>(
442 this IEnumerable<TSource> source,
445 if (source == null) throw new ArgumentNullException("source");
447 var list = source as IList<TSource>; // optimized case for lists
449 return list.Count > 0 ? list[list.Count - 1] : empty();
451 using (var e = source.GetEnumerator())
456 var last = e.Current;
465 /// Returns the last element of a sequence.
467 public static TSource Last<TSource>(
468 this IEnumerable<TSource> source)
470 return source.LastImpl(Futures<TSource>.Undefined);
474 /// Returns the last element of a sequence that satisfies a
475 /// specified condition.
478 public static TSource Last<TSource>(
479 this IEnumerable<TSource> source,
480 Func<TSource, bool> predicate)
482 return Last(source.Where(predicate));
486 /// Returns the last element of a sequence, or a default value if
487 /// the sequence contains no elements.
490 public static TSource LastOrDefault<TSource>(
491 this IEnumerable<TSource> source)
493 return source.LastImpl(Futures<TSource>.Default);
497 /// Returns the last element of a sequence that satisfies a
498 /// condition or a default value if no such element is found.
501 public static TSource LastOrDefault<TSource>(
502 this IEnumerable<TSource> source,
503 Func<TSource, bool> predicate)
505 return LastOrDefault(source.Where(predicate));
509 /// Base implementation of Single operator.
512 private static TSource SingleImpl<TSource>(
513 this IEnumerable<TSource> source,
516 if (source == null) throw new ArgumentNullException("source");
518 using (var e = source.GetEnumerator())
522 var single = e.Current;
526 throw new InvalidOperationException();
534 /// Returns the only element of a sequence, and throws an exception
535 /// if there is not exactly one element in the sequence.
538 public static TSource Single<TSource>(
539 this IEnumerable<TSource> source)
541 return source.SingleImpl(Futures<TSource>.Undefined);
545 /// Returns the only element of a sequence that satisfies a
546 /// specified condition, and throws an exception if more than one
547 /// such element exists.
550 public static TSource Single<TSource>(
551 this IEnumerable<TSource> source,
552 Func<TSource, bool> predicate)
554 return Single(source.Where(predicate));
558 /// Returns the only element of a sequence, or a default value if
559 /// the sequence is empty; this method throws an exception if there
560 /// is more than one element in the sequence.
563 public static TSource SingleOrDefault<TSource>(
564 this IEnumerable<TSource> source)
566 return source.SingleImpl(Futures<TSource>.Default);
570 /// Returns the only element of a sequence that satisfies a
571 /// specified condition or a default value if no such element
572 /// exists; this method throws an exception if more than one element
573 /// satisfies the condition.
576 public static TSource SingleOrDefault<TSource>(
577 this IEnumerable<TSource> source,
578 Func<TSource, bool> predicate)
580 return SingleOrDefault(source.Where(predicate));
584 /// Returns the element at a specified index in a sequence.
587 public static TSource ElementAt<TSource>(
588 this IEnumerable<TSource> source,
591 if (source == null) throw new ArgumentNullException("source");
594 throw new ArgumentOutOfRangeException("index", index, null);
596 var list = source as IList<TSource>;
602 return source.SkipWhile((item, i) => i < index).First();
604 catch (InvalidOperationException) // if thrown by First
606 throw new ArgumentOutOfRangeException("index", index, null);
611 /// Returns the element at a specified index in a sequence or a
612 /// default value if the index is out of range.
615 public static TSource ElementAtOrDefault<TSource>(
616 this IEnumerable<TSource> source,
619 if (source == null) throw new ArgumentNullException("source");
622 return default(TSource);
624 var list = source as IList<TSource>;
626 return index < list.Count ? list[index] : default(TSource);
628 return source.SkipWhile((item, i) => i < index).FirstOrDefault();
632 /// Inverts the order of the elements in a sequence.
635 public static IEnumerable<TSource> Reverse<TSource>(
636 this IEnumerable<TSource> source)
638 if (source == null) throw new ArgumentNullException("source");
640 return ReverseYield(source);
643 private static IEnumerable<TSource> ReverseYield<TSource>(IEnumerable<TSource> source)
645 var stack = new Stack<TSource>();
646 foreach (var item in source)
649 foreach (var item in stack)
654 /// Bypasses elements in a sequence as long as a specified condition
655 /// is true and then returns the remaining elements.
658 public static IEnumerable<TSource> SkipWhile<TSource>(
659 this IEnumerable<TSource> source,
660 Func<TSource, bool> predicate)
662 if (predicate == null) throw new ArgumentNullException("predicate");
664 return source.SkipWhile((item, i) => predicate(item));
668 /// Bypasses elements in a sequence as long as a specified condition
669 /// is true and then returns the remaining elements. The element's
670 /// index is used in the logic of the predicate function.
673 public static IEnumerable<TSource> SkipWhile<TSource>(
674 this IEnumerable<TSource> source,
675 Func<TSource, int, bool> predicate)
677 if (source == null) throw new ArgumentNullException("source");
678 if (predicate == null) throw new ArgumentNullException("predicate");
680 return SkipWhileYield(source, predicate);
683 private static IEnumerable<TSource> SkipWhileYield<TSource>(
684 IEnumerable<TSource> source,
685 Func<TSource, int, bool> predicate)
687 using (var e = source.GetEnumerator())
689 for (var i = 0; ; i++)
694 if (!predicate(e.Current, i))
698 do { yield return e.Current; } while (e.MoveNext());
703 /// Bypasses a specified number of elements in a sequence and then
704 /// returns the remaining elements.
707 public static IEnumerable<TSource> Skip<TSource>(
708 this IEnumerable<TSource> source,
711 return source.SkipWhile((item, i) => i < count);
715 /// Returns the number of elements in a sequence.
718 public static int Count<TSource>(
719 this IEnumerable<TSource> source)
721 if (source == null) throw new ArgumentNullException("source");
723 var collection = source as ICollection;
724 return collection != null
726 : source.Aggregate(0, (count, item) => checked(count + 1));
730 /// Returns a number that represents how many elements in the
731 /// specified sequence satisfy a condition.
734 public static int Count<TSource>(
735 this IEnumerable<TSource> source,
736 Func<TSource, bool> predicate)
738 return Count(source.Where(predicate));
742 /// Returns an <see cref="Int64"/> that represents the total number
743 /// of elements in a sequence.
746 public static long LongCount<TSource>(
747 this IEnumerable<TSource> source)
749 if (source == null) throw new ArgumentNullException("source");
751 var array = source as Array;
754 : source.Aggregate(0L, (count, item) => count + 1);
758 /// Returns an <see cref="Int64"/> that represents how many elements
759 /// in a sequence satisfy a condition.
762 public static long LongCount<TSource>(
763 this IEnumerable<TSource> source,
764 Func<TSource, bool> predicate)
766 return LongCount(source.Where(predicate));
770 /// Concatenates two sequences.
773 public static IEnumerable<TSource> Concat<TSource>(
774 this IEnumerable<TSource> first,
775 IEnumerable<TSource> second)
777 if (first == null) throw new ArgumentNullException("first");
778 if (second == null) throw new ArgumentNullException("second");
780 return ConcatYield(first, second);
783 private static IEnumerable<TSource> ConcatYield<TSource>(
784 IEnumerable<TSource> first,
785 IEnumerable<TSource> second)
787 foreach (var item in first)
790 foreach (var item in second)
795 /// Creates a <see cref="List{T}"/> from an <see cref="IEnumerable{T}"/>.
798 public static List<TSource> ToList<TSource>(
799 this IEnumerable<TSource> source)
801 if (source == null) throw new ArgumentNullException("source");
803 return new List<TSource>(source);
807 /// Creates an array from an <see cref="IEnumerable{T}"/>.
810 public static TSource[] ToArray<TSource>(
811 this IEnumerable<TSource> source)
813 return source.ToList().ToArray();
817 /// Returns distinct elements from a sequence by using the default
818 /// equality comparer to compare values.
821 public static IEnumerable<TSource> Distinct<TSource>(
822 this IEnumerable<TSource> source)
824 return Distinct(source, /* comparer */ null);
828 /// Returns distinct elements from a sequence by using a specified
829 /// <see cref="IEqualityComparer{T}"/> to compare values.
832 public static IEnumerable<TSource> Distinct<TSource>(
833 this IEnumerable<TSource> source,
834 IEqualityComparer<TSource> comparer)
836 if (source == null) throw new ArgumentNullException("source");
838 return DistinctYield(source, comparer);
841 private static IEnumerable<TSource> DistinctYield<TSource>(
842 IEnumerable<TSource> source,
843 IEqualityComparer<TSource> comparer)
845 var set = new Dictionary<TSource, object>(comparer);
848 foreach (var item in source)
858 if (set.ContainsKey(item))
868 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
869 /// <see cref="IEnumerable{T}" /> according to a specified key
870 /// selector function.
873 public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
874 this IEnumerable<TSource> source,
875 Func<TSource, TKey> keySelector)
877 return ToLookup(source, keySelector, e => e, /* comparer */ null);
881 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
882 /// <see cref="IEnumerable{T}" /> according to a specified key
883 /// selector function and a key comparer.
886 public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
887 this IEnumerable<TSource> source,
888 Func<TSource, TKey> keySelector,
889 IEqualityComparer<TKey> comparer)
891 return ToLookup(source, keySelector, e => e, comparer);
895 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
896 /// <see cref="IEnumerable{T}" /> according to specified key
897 /// and element selector functions.
900 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
901 this IEnumerable<TSource> source,
902 Func<TSource, TKey> keySelector,
903 Func<TSource, TElement> elementSelector)
905 return ToLookup(source, keySelector, elementSelector, /* comparer */ null);
909 /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
910 /// <see cref="IEnumerable{T}" /> according to a specified key
911 /// selector function, a comparer and an element selector function.
914 public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
915 this IEnumerable<TSource> source,
916 Func<TSource, TKey> keySelector,
917 Func<TSource, TElement> elementSelector,
918 IEqualityComparer<TKey> comparer)
920 if (source == null) throw new ArgumentNullException("source");
921 if (keySelector == null) throw new ArgumentNullException("keySelector");
922 if (elementSelector == null) throw new ArgumentNullException("elementSelector");
924 var lookup = new Lookup<TKey, TElement>(comparer);
926 foreach (var item in source)
928 var key = keySelector(item);
930 var grouping = (Grouping<TKey, TElement>) lookup.Find(key);
931 if (grouping == null)
933 grouping = new Grouping<TKey, TElement>(key);
934 lookup.Add(grouping);
937 grouping.Add(elementSelector(item));
944 /// Groups the elements of a sequence according to a specified key
945 /// selector function.
948 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
949 this IEnumerable<TSource> source,
950 Func<TSource, TKey> keySelector)
952 return GroupBy(source, keySelector, /* comparer */ null);
956 /// Groups the elements of a sequence according to a specified key
957 /// selector function and compares the keys by using a specified
961 public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
962 this IEnumerable<TSource> source,
963 Func<TSource, TKey> keySelector,
964 IEqualityComparer<TKey> comparer)
966 return GroupBy(source, keySelector, e => e, comparer);
970 /// Groups the elements of a sequence according to a specified key
971 /// selector function and projects the elements for each group by
972 /// using a specified function.
975 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
976 this IEnumerable<TSource> source,
977 Func<TSource, TKey> keySelector,
978 Func<TSource, TElement> elementSelector)
980 return GroupBy(source, keySelector, elementSelector, /* comparer */ null);
984 /// Groups the elements of a sequence according to a specified key
985 /// selector function and creates a result value from each group and
989 public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
990 this IEnumerable<TSource> source,
991 Func<TSource, TKey> keySelector,
992 Func<TSource, TElement> elementSelector,
993 IEqualityComparer<TKey> comparer)
995 if (source == null) throw new ArgumentNullException("source");
996 if (keySelector == null) throw new ArgumentNullException("keySelector");
997 if (elementSelector == null) throw new ArgumentNullException("elementSelector");
999 return ToLookup(source, keySelector, elementSelector, comparer);
1003 /// Groups the elements of a sequence according to a key selector
1004 /// function. The keys are compared by using a comparer and each
1005 /// group's elements are projected by using a specified function.
1008 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
1009 this IEnumerable<TSource> source,
1010 Func<TSource, TKey> keySelector,
1011 Func<TKey, IEnumerable<TSource>, TResult> resultSelector)
1013 return GroupBy(source, keySelector, resultSelector, /* comparer */ null);
1017 /// Groups the elements of a sequence according to a specified key
1018 /// selector function and creates a result value from each group and
1019 /// its key. The elements of each group are projected by using a
1020 /// specified function.
1023 public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
1024 this IEnumerable<TSource> source,
1025 Func<TSource, TKey> keySelector,
1026 Func<TKey, IEnumerable<TSource>, TResult> resultSelector,
1027 IEqualityComparer<TKey> comparer)
1029 if (source == null) throw new ArgumentNullException("source");
1030 if (keySelector == null) throw new ArgumentNullException("keySelector");
1031 if (resultSelector == null) throw new ArgumentNullException("resultSelector");
1033 return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g));
1037 /// Groups the elements of a sequence according to a specified key
1038 /// selector function and creates a result value from each group and
1039 /// its key. The keys are compared by using a specified comparer.
1042 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
1043 this IEnumerable<TSource> source,
1044 Func<TSource, TKey> keySelector,
1045 Func<TSource, TElement> elementSelector,
1046 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
1048 return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null);
1052 /// Groups the elements of a sequence according to a specified key
1053 /// selector function and creates a result value from each group and
1054 /// its key. Key values are compared by using a specified comparer,
1055 /// and the elements of each group are projected by using a
1056 /// specified function.
1059 public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
1060 this IEnumerable<TSource> source,
1061 Func<TSource, TKey> keySelector,
1062 Func<TSource, TElement> elementSelector,
1063 Func<TKey, IEnumerable<TElement>, TResult> resultSelector,
1064 IEqualityComparer<TKey> comparer)
1066 if (source == null) throw new ArgumentNullException("source");
1067 if (keySelector == null) throw new ArgumentNullException("keySelector");
1068 if (elementSelector == null) throw new ArgumentNullException("elementSelector");
1069 if (resultSelector == null) throw new ArgumentNullException("resultSelector");
1071 return ToLookup(source, keySelector, elementSelector, comparer)
1072 .Select(g => resultSelector(g.Key, g));
1076 /// Applies an accumulator function over a sequence.
1079 public static TSource Aggregate<TSource>(
1080 this IEnumerable<TSource> source,
1081 Func<TSource, TSource, TSource> func)
1083 if (source == null) throw new ArgumentNullException("source");
1084 if (func == null) throw new ArgumentNullException("func");
1086 using (var e = source.GetEnumerator())
1089 throw new InvalidOperationException();
1091 return e.Renumerable().Skip(1).Aggregate(e.Current, func);
1096 /// Applies an accumulator function over a sequence. The specified
1097 /// seed value is used as the initial accumulator value.
1100 public static TAccumulate Aggregate<TSource, TAccumulate>(
1101 this IEnumerable<TSource> source,
1103 Func<TAccumulate, TSource, TAccumulate> func)
1105 return Aggregate(source, seed, func, r => r);
1109 /// Applies an accumulator function over a sequence. The specified
1110 /// seed value is used as the initial accumulator value, and the
1111 /// specified function is used to select the result value.
1114 public static TResult Aggregate<TSource, TAccumulate, TResult>(
1115 this IEnumerable<TSource> source,
1117 Func<TAccumulate, TSource, TAccumulate> func,
1118 Func<TAccumulate, TResult> resultSelector)
1120 if (source == null) throw new ArgumentNullException("source");
1121 if (func == null) throw new ArgumentNullException("func");
1122 if (resultSelector == null) throw new ArgumentNullException("resultSelector");
1126 foreach (var item in source)
1127 result = func(result, item);
1129 return resultSelector(result);
1133 /// Produces the set union of two sequences by using the default
1134 /// equality comparer.
1137 public static IEnumerable<TSource> Union<TSource>(
1138 this IEnumerable<TSource> first,
1139 IEnumerable<TSource> second)
1141 return Union(first, second, /* comparer */ null);
1145 /// Produces the set union of two sequences by using a specified
1146 /// <see cref="IEqualityComparer{T}" />.
1149 public static IEnumerable<TSource> Union<TSource>(
1150 this IEnumerable<TSource> first,
1151 IEnumerable<TSource> second,
1152 IEqualityComparer<TSource> comparer)
1154 return first.Concat(second).Distinct(comparer);
1158 /// Returns the elements of the specified sequence or the type
1159 /// parameter's default value in a singleton collection if the
1160 /// sequence is empty.
1163 public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
1164 this IEnumerable<TSource> source)
1166 return source.DefaultIfEmpty(default(TSource));
1170 /// Returns the elements of the specified sequence or the specified
1171 /// value in a singleton collection if the sequence is empty.
1174 public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
1175 this IEnumerable<TSource> source,
1176 TSource defaultValue)
1178 if (source == null) throw new ArgumentNullException("source");
1180 return DefaultIfEmptyYield(source, defaultValue);
1183 private static IEnumerable<TSource> DefaultIfEmptyYield<TSource>(
1184 IEnumerable<TSource> source,
1185 TSource defaultValue)
1187 using (var e = source.GetEnumerator())
1190 yield return defaultValue;
1192 do { yield return e.Current; } while (e.MoveNext());
1197 /// Determines whether all elements of a sequence satisfy a condition.
1200 public static bool All<TSource>(
1201 this IEnumerable<TSource> source,
1202 Func<TSource, bool> predicate)
1204 if (source == null) throw new ArgumentNullException("source");
1205 if (predicate == null) throw new ArgumentNullException("predicate");
1207 foreach (var item in source)
1208 if (!predicate(item))
1215 /// Determines whether a sequence contains any elements.
1218 public static bool Any<TSource>(
1219 this IEnumerable<TSource> source)
1221 if (source == null) throw new ArgumentNullException("source");
1223 using (var e = source.GetEnumerator())
1224 return e.MoveNext();
1228 /// Determines whether any element of a sequence satisfies a
1232 public static bool Any<TSource>(
1233 this IEnumerable<TSource> source,
1234 Func<TSource, bool> predicate)
1236 return source.Where(predicate).Any();
1240 /// Determines whether a sequence contains a specified element by
1241 /// using the default equality comparer.
1244 public static bool Contains<TSource>(
1245 this IEnumerable<TSource> source,
1248 return source.Contains(value, /* comparer */ null);
1252 /// Determines whether a sequence contains a specified element by
1253 /// using a specified <see cref="IEqualityComparer{T}" />.
1256 public static bool Contains<TSource>(
1257 this IEnumerable<TSource> source,
1259 IEqualityComparer<TSource> comparer)
1261 if (source == null) throw new ArgumentNullException("source");
1263 if (comparer == null)
1265 var collection = source as ICollection<TSource>;
1266 if (collection != null)
1267 return collection.Contains(value);
1270 comparer = comparer ?? EqualityComparer<TSource>.Default;
1271 return source.Any(item => comparer.Equals(item, value));
1275 /// Determines whether two sequences are equal by comparing the
1276 /// elements by using the default equality comparer for their type.
1279 public static bool SequenceEqual<TSource>(
1280 this IEnumerable<TSource> first,
1281 IEnumerable<TSource> second)
1283 return first.SequenceEqual(second, /* comparer */ null);
1287 /// Determines whether two sequences are equal by comparing their
1288 /// elements by using a specified <see cref="IEqualityComparer{T}" />.
1291 public static bool SequenceEqual<TSource>(
1292 this IEnumerable<TSource> first,
1293 IEnumerable<TSource> second,
1294 IEqualityComparer<TSource> comparer)
1296 if (first == null) throw new ArgumentNullException("frist");
1297 if (second == null) throw new ArgumentNullException("second");
1299 comparer = comparer ?? EqualityComparer<TSource>.Default;
1301 using (IEnumerator<TSource> lhs = first.GetEnumerator(),
1302 rhs = second.GetEnumerator())
1306 if (!lhs.MoveNext())
1307 return !rhs.MoveNext();
1309 if (!rhs.MoveNext())
1312 while (comparer.Equals(lhs.Current, rhs.Current));
1319 /// Base implementation for Min/Max operator.
1322 private static TSource MinMaxImpl<TSource>(
1323 this IEnumerable<TSource> source,
1324 Func<TSource, TSource, bool> lesser)
1326 if (source == null) throw new ArgumentNullException("source");
1327 Debug.Assert(lesser != null);
1329 if (typeof(TSource).IsClass) // ReSharper disable CompareNonConstrainedGenericWithNull
1330 source = source.Where(e => e != null).DefaultIfEmpty(); // ReSharper restore CompareNonConstrainedGenericWithNull
1332 return source.Aggregate((a, item) => lesser(a, item) ? a : item);
1336 /// Base implementation for Min/Max operator for nullable types.
1339 private static TSource? MinMaxImpl<TSource>(
1340 this IEnumerable<TSource?> source,
1341 TSource? seed, Func<TSource?, TSource?, bool> lesser) where TSource : struct
1343 if (source == null) throw new ArgumentNullException("source");
1344 Debug.Assert(lesser != null);
1346 return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item);
1347 // == MinMaxImpl(Repeat<TSource?>(null, 1).Concat(source), lesser);
1351 /// Returns the minimum value in a generic sequence.
1354 public static TSource Min<TSource>(
1355 this IEnumerable<TSource> source)
1357 var comparer = Comparer<TSource>.Default;
1358 return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0);
1362 /// Invokes a transform function on each element of a generic
1363 /// sequence and returns the minimum resulting value.
1366 public static TResult Min<TSource, TResult>(
1367 this IEnumerable<TSource> source,
1368 Func<TSource, TResult> selector)
1370 return source.Select(selector).Min();
1374 /// Returns the maximum value in a generic sequence.
1377 public static TSource Max<TSource>(
1378 this IEnumerable<TSource> source)
1380 var comparer = Comparer<TSource>.Default;
1381 return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0);
1385 /// Invokes a transform function on each element of a generic
1386 /// sequence and returns the maximum resulting value.
1389 public static TResult Max<TSource, TResult>(
1390 this IEnumerable<TSource> source,
1391 Func<TSource, TResult> selector)
1393 return source.Select(selector).Max();
1397 /// Makes an enumerator seen as enumerable once more.
1400 /// The supplied enumerator must have been started. The first element
1401 /// returned is the element the enumerator was on when passed in.
1402 /// DO NOT use this method if the caller must be a generator. It is
1403 /// mostly safe among aggregate operations.
1406 private static IEnumerable<T> Renumerable<T>(this IEnumerator<T> e)
1408 Debug.Assert(e != null);
1410 do { yield return e.Current; } while (e.MoveNext());
1414 /// Sorts the elements of a sequence in ascending order according to a key.
1417 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
1418 this IEnumerable<TSource> source,
1419 Func<TSource, TKey> keySelector)
1421 return source.OrderBy(keySelector, /* comparer */ null);
1425 /// Sorts the elements of a sequence in ascending order by using a
1426 /// specified comparer.
1429 public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
1430 this IEnumerable<TSource> source,
1431 Func<TSource, TKey> keySelector,
1432 IComparer<TKey> comparer)
1434 if (source == null) throw new ArgumentNullException("source");
1435 if (keySelector == null) throw new ArgumentNullException("keySelector");
1437 return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ false);
1441 /// Sorts the elements of a sequence in descending order according to a key.
1444 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
1445 this IEnumerable<TSource> source,
1446 Func<TSource, TKey> keySelector)
1448 return source.OrderByDescending(keySelector, /* comparer */ null);
1452 /// Sorts the elements of a sequence in descending order by using a
1453 /// specified comparer.
1456 public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
1457 this IEnumerable<TSource> source,
1458 Func<TSource, TKey> keySelector,
1459 IComparer<TKey> comparer)
1461 if (source == null) throw new ArgumentNullException("source");
1462 if (source == null) throw new ArgumentNullException("keySelector");
1464 return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ true);
1468 /// Performs a subsequent ordering of the elements in a sequence in
1469 /// ascending order according to a key.
1472 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
1473 this IOrderedEnumerable<TSource> source,
1474 Func<TSource, TKey> keySelector)
1476 return source.ThenBy(keySelector, /* comparer */ null);
1480 /// Performs a subsequent ordering of the elements in a sequence in
1481 /// ascending order by using a specified comparer.
1484 public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
1485 this IOrderedEnumerable<TSource> source,
1486 Func<TSource, TKey> keySelector,
1487 IComparer<TKey> comparer)
1489 if (source == null) throw new ArgumentNullException("source");
1491 return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false);
1495 /// Performs a subsequent ordering of the elements in a sequence in
1496 /// descending order, according to a key.
1499 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
1500 this IOrderedEnumerable<TSource> source,
1501 Func<TSource, TKey> keySelector)
1503 return source.ThenByDescending(keySelector, /* comparer */ null);
1507 /// Performs a subsequent ordering of the elements in a sequence in
1508 /// descending order by using a specified comparer.
1511 public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
1512 this IOrderedEnumerable<TSource> source,
1513 Func<TSource, TKey> keySelector,
1514 IComparer<TKey> comparer)
1516 if (source == null) throw new ArgumentNullException("source");
1518 return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true);
1522 /// Base implementation for Intersect and Except operators.
1525 private static IEnumerable<TSource> IntersectExceptImpl<TSource>(
1526 this IEnumerable<TSource> first,
1527 IEnumerable<TSource> second,
1528 IEqualityComparer<TSource> comparer,
1531 if (first == null) throw new ArgumentNullException("first");
1532 if (second == null) throw new ArgumentNullException("second");
1534 var keys = new List<Key<TSource>>();
1535 var flags = new Dictionary<Key<TSource>, bool>(new KeyComparer<TSource>(comparer));
1537 foreach (var item in from item in first
1538 select new Key<TSource>(item) into item
1539 where !flags.ContainsKey(item)
1542 flags.Add(item, !flag);
1546 foreach (var item in from item in second
1547 select new Key<TSource>(item) into item
1548 where flags.ContainsKey(item)
1555 // As per docs, "the marked elements are yielded in the order in
1556 // which they were collected.
1559 return from item in keys where flags[item] select item.Value;
1563 /// Produces the set intersection of two sequences by using the
1564 /// default equality comparer to compare values.
1567 public static IEnumerable<TSource> Intersect<TSource>(
1568 this IEnumerable<TSource> first,
1569 IEnumerable<TSource> second)
1571 return first.Intersect(second, /* comparer */ null);
1575 /// Produces the set intersection of two sequences by using the
1576 /// specified <see cref="IEqualityComparer{T}" /> to compare values.
1579 public static IEnumerable<TSource> Intersect<TSource>(
1580 this IEnumerable<TSource> first,
1581 IEnumerable<TSource> second,
1582 IEqualityComparer<TSource> comparer)
1584 return IntersectExceptImpl(first, second, comparer, /* flag */ true);
1588 /// Produces the set difference of two sequences by using the
1589 /// default equality comparer to compare values.
1592 public static IEnumerable<TSource> Except<TSource>(
1593 this IEnumerable<TSource> first,
1594 IEnumerable<TSource> second)
1596 return first.Except(second, /* comparer */ null);
1600 /// Produces the set difference of two sequences by using the
1601 /// specified <see cref="IEqualityComparer{T}" /> to compare values.
1604 public static IEnumerable<TSource> Except<TSource>(
1605 this IEnumerable<TSource> first,
1606 IEnumerable<TSource> second,
1607 IEqualityComparer<TSource> comparer)
1609 return IntersectExceptImpl(first, second, comparer, /* flag */ false);
1613 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
1614 /// <see cref="IEnumerable{T}" /> according to a specified key
1615 /// selector function.
1618 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
1619 this IEnumerable<TSource> source,
1620 Func<TSource, TKey> keySelector)
1622 return source.ToDictionary(keySelector, /* comparer */ null);
1626 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
1627 /// <see cref="IEnumerable{T}" /> according to a specified key
1628 /// selector function and key comparer.
1631 public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
1632 this IEnumerable<TSource> source,
1633 Func<TSource, TKey> keySelector,
1634 IEqualityComparer<TKey> comparer)
1636 return source.ToDictionary(keySelector, e => e, comparer);
1640 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
1641 /// <see cref="IEnumerable{T}" /> according to specified key
1642 /// selector and element selector functions.
1645 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
1646 this IEnumerable<TSource> source,
1647 Func<TSource, TKey> keySelector,
1648 Func<TSource, TElement> elementSelector)
1650 return source.ToDictionary(keySelector, elementSelector, /* comparer */ null);
1654 /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
1655 /// <see cref="IEnumerable{T}" /> according to a specified key
1656 /// selector function, a comparer, and an element selector function.
1659 public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
1660 this IEnumerable<TSource> source,
1661 Func<TSource, TKey> keySelector,
1662 Func<TSource, TElement> elementSelector,
1663 IEqualityComparer<TKey> comparer)
1665 if (source == null) throw new ArgumentNullException("source");
1666 if (keySelector == null) throw new ArgumentNullException("keySelector");
1667 if (elementSelector == null) throw new ArgumentNullException("elementSelector");
1669 var dict = new Dictionary<TKey, TElement>(comparer);
1671 foreach (var item in source)
1674 // ToDictionary is meant to throw ArgumentNullException if
1675 // keySelector produces a key that is null and
1676 // Argument exception if keySelector produces duplicate keys
1677 // for two elements. Incidentally, the doucmentation for
1678 // IDictionary<TKey, TValue>.Add says that the Add method
1679 // throws the same exceptions under the same circumstances
1680 // so we don't need to do any additional checking or work
1681 // here and let the Add implementation do all the heavy
1685 dict.Add(keySelector(item), elementSelector(item));
1692 /// Correlates the elements of two sequences based on matching keys.
1693 /// The default equality comparer is used to compare keys.
1696 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
1697 this IEnumerable<TOuter> outer,
1698 IEnumerable<TInner> inner,
1699 Func<TOuter, TKey> outerKeySelector,
1700 Func<TInner, TKey> innerKeySelector,
1701 Func<TOuter, TInner, TResult> resultSelector)
1703 return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
1707 /// Correlates the elements of two sequences based on matching keys.
1708 /// The default equality comparer is used to compare keys. A
1709 /// specified <see cref="IEqualityComparer{T}" /> is used to compare keys.
1712 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
1713 this IEnumerable<TOuter> outer,
1714 IEnumerable<TInner> inner,
1715 Func<TOuter, TKey> outerKeySelector,
1716 Func<TInner, TKey> innerKeySelector,
1717 Func<TOuter, TInner, TResult> resultSelector,
1718 IEqualityComparer<TKey> comparer)
1720 if (outer == null) throw new ArgumentNullException("outer");
1721 if (inner == null) throw new ArgumentNullException("inner");
1722 if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
1723 if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
1724 if (resultSelector == null) throw new ArgumentNullException("resultSelector");
1726 var lookup = inner.ToLookup(innerKeySelector, comparer);
1730 from i in lookup[outerKeySelector(o)]
1731 select resultSelector(o, i);
1735 /// Correlates the elements of two sequences based on equality of
1736 /// keys and groups the results. The default equality comparer is
1737 /// used to compare keys.
1740 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
1741 this IEnumerable<TOuter> outer,
1742 IEnumerable<TInner> inner,
1743 Func<TOuter, TKey> outerKeySelector,
1744 Func<TInner, TKey> innerKeySelector,
1745 Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)
1747 return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
1751 /// Correlates the elements of two sequences based on equality of
1752 /// keys and groups the results. The default equality comparer is
1753 /// used to compare keys. A specified <see cref="IEqualityComparer{T}" />
1754 /// is used to compare keys.
1757 public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
1758 this IEnumerable<TOuter> outer,
1759 IEnumerable<TInner> inner,
1760 Func<TOuter, TKey> outerKeySelector,
1761 Func<TInner, TKey> innerKeySelector,
1762 Func<TOuter, IEnumerable<TInner>, TResult> resultSelector,
1763 IEqualityComparer<TKey> comparer)
1765 if (outer == null) throw new ArgumentNullException("outer");
1766 if (inner == null) throw new ArgumentNullException("inner");
1767 if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
1768 if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
1769 if (resultSelector == null) throw new ArgumentNullException("resultSelector");
1771 var lookup = inner.ToLookup(innerKeySelector, comparer);
1772 return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)]));
1775 private static class Sequence<T>
1777 public static readonly IEnumerable<T> Empty = new T[0];
1780 private sealed class Grouping<K, V> : List<V>, IGrouping<K, V>
1782 internal Grouping(K key)
1787 public K Key { get; private set; }
1792 // $Id: Enumerable.g.tt 71137f497bf2 2012/04/16 20:01:27 azizatif $
1794 namespace System.Linq
1799 using System.Collections.Generic;
1803 // This partial implementation was template-generated:
1804 // Mon, 16 Apr 2012 20:05:53 GMT
1806 partial class Enumerable
1809 /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> values.
1812 public static int Sum(
1813 this IEnumerable<int> source)
1815 if (source == null) throw new ArgumentNullException("source");
1818 foreach (var num in source)
1819 sum = checked(sum + num);
1825 /// Computes the sum of a sequence of nullable <see cref="System.Int32" />
1826 /// values that are obtained by invoking a transform function on
1827 /// each element of the input sequence.
1830 public static int Sum<TSource>(
1831 this IEnumerable<TSource> source,
1832 Func<TSource, int> selector)
1834 return source.Select(selector).Sum();
1838 /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values.
1841 public static double Average(
1842 this IEnumerable<int> source)
1844 if (source == null) throw new ArgumentNullException("source");
1849 foreach (var num in source)
1857 throw new InvalidOperationException();
1859 return (double) sum / count;
1863 /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values
1864 /// that are obtained by invoking a transform function on each
1865 /// element of the input sequence.
1868 public static double Average<TSource>(
1869 this IEnumerable<TSource> source,
1870 Func<TSource, int> selector)
1872 return source.Select(selector).Average();
1877 /// Computes the sum of a sequence of <see cref="System.Int32" /> values.
1880 public static int? Sum(
1881 this IEnumerable<int?> source)
1883 if (source == null) throw new ArgumentNullException("source");
1886 foreach (var num in source)
1887 sum = checked(sum + (num ?? 0));
1893 /// Computes the sum of a sequence of <see cref="System.Int32" />
1894 /// values that are obtained by invoking a transform function on
1895 /// each element of the input sequence.
1898 public static int? Sum<TSource>(
1899 this IEnumerable<TSource> source,
1900 Func<TSource, int?> selector)
1902 return source.Select(selector).Sum();
1906 /// Computes the average of a sequence of <see cref="System.Int32" /> values.
1909 public static double? Average(
1910 this IEnumerable<int?> source)
1912 if (source == null) throw new ArgumentNullException("source");
1917 foreach (var num in source.Where(n => n != null))
1927 return (double?) sum / count;
1931 /// Computes the average of a sequence of <see cref="System.Int32" /> values
1932 /// that are obtained by invoking a transform function on each
1933 /// element of the input sequence.
1936 public static double? Average<TSource>(
1937 this IEnumerable<TSource> source,
1938 Func<TSource, int?> selector)
1940 return source.Select(selector).Average();
1944 /// Returns the minimum value in a sequence of nullable
1945 /// <see cref="System.Int32" /> values.
1948 public static int? Min(
1949 this IEnumerable<int?> source)
1951 if (source == null) throw new ArgumentNullException("source");
1953 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
1957 /// Invokes a transform function on each element of a sequence and
1958 /// returns the minimum nullable <see cref="System.Int32" /> value.
1961 public static int? Min<TSource>(
1962 this IEnumerable<TSource> source,
1963 Func<TSource, int?> selector)
1965 return source.Select(selector).Min();
1969 /// Returns the maximum value in a sequence of nullable
1970 /// <see cref="System.Int32" /> values.
1973 public static int? Max(
1974 this IEnumerable<int?> source)
1976 if (source == null) throw new ArgumentNullException("source");
1978 return MinMaxImpl(source.Where(x => x != null),
1979 null, (max, x) => x == null || (max != null && x.Value < max.Value));
1983 /// Invokes a transform function on each element of a sequence and
1984 /// returns the maximum nullable <see cref="System.Int32" /> value.
1987 public static int? Max<TSource>(
1988 this IEnumerable<TSource> source,
1989 Func<TSource, int?> selector)
1991 return source.Select(selector).Max();
1995 /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> values.
1998 public static long Sum(
1999 this IEnumerable<long> source)
2001 if (source == null) throw new ArgumentNullException("source");
2004 foreach (var num in source)
2005 sum = checked(sum + num);
2011 /// Computes the sum of a sequence of nullable <see cref="System.Int64" />
2012 /// values that are obtained by invoking a transform function on
2013 /// each element of the input sequence.
2016 public static long Sum<TSource>(
2017 this IEnumerable<TSource> source,
2018 Func<TSource, long> selector)
2020 return source.Select(selector).Sum();
2024 /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values.
2027 public static double Average(
2028 this IEnumerable<long> source)
2030 if (source == null) throw new ArgumentNullException("source");
2035 foreach (var num in source)
2043 throw new InvalidOperationException();
2045 return (double) sum / count;
2049 /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values
2050 /// that are obtained by invoking a transform function on each
2051 /// element of the input sequence.
2054 public static double Average<TSource>(
2055 this IEnumerable<TSource> source,
2056 Func<TSource, long> selector)
2058 return source.Select(selector).Average();
2063 /// Computes the sum of a sequence of <see cref="System.Int64" /> values.
2066 public static long? Sum(
2067 this IEnumerable<long?> source)
2069 if (source == null) throw new ArgumentNullException("source");
2072 foreach (var num in source)
2073 sum = checked(sum + (num ?? 0));
2079 /// Computes the sum of a sequence of <see cref="System.Int64" />
2080 /// values that are obtained by invoking a transform function on
2081 /// each element of the input sequence.
2084 public static long? Sum<TSource>(
2085 this IEnumerable<TSource> source,
2086 Func<TSource, long?> selector)
2088 return source.Select(selector).Sum();
2092 /// Computes the average of a sequence of <see cref="System.Int64" /> values.
2095 public static double? Average(
2096 this IEnumerable<long?> source)
2098 if (source == null) throw new ArgumentNullException("source");
2103 foreach (var num in source.Where(n => n != null))
2113 return (double?) sum / count;
2117 /// Computes the average of a sequence of <see cref="System.Int64" /> values
2118 /// that are obtained by invoking a transform function on each
2119 /// element of the input sequence.
2122 public static double? Average<TSource>(
2123 this IEnumerable<TSource> source,
2124 Func<TSource, long?> selector)
2126 return source.Select(selector).Average();
2130 /// Returns the minimum value in a sequence of nullable
2131 /// <see cref="System.Int64" /> values.
2134 public static long? Min(
2135 this IEnumerable<long?> source)
2137 if (source == null) throw new ArgumentNullException("source");
2139 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
2143 /// Invokes a transform function on each element of a sequence and
2144 /// returns the minimum nullable <see cref="System.Int64" /> value.
2147 public static long? Min<TSource>(
2148 this IEnumerable<TSource> source,
2149 Func<TSource, long?> selector)
2151 return source.Select(selector).Min();
2155 /// Returns the maximum value in a sequence of nullable
2156 /// <see cref="System.Int64" /> values.
2159 public static long? Max(
2160 this IEnumerable<long?> source)
2162 if (source == null) throw new ArgumentNullException("source");
2164 return MinMaxImpl(source.Where(x => x != null),
2165 null, (max, x) => x == null || (max != null && x.Value < max.Value));
2169 /// Invokes a transform function on each element of a sequence and
2170 /// returns the maximum nullable <see cref="System.Int64" /> value.
2173 public static long? Max<TSource>(
2174 this IEnumerable<TSource> source,
2175 Func<TSource, long?> selector)
2177 return source.Select(selector).Max();
2181 /// Computes the sum of a sequence of nullable <see cref="System.Single" /> values.
2184 public static float Sum(
2185 this IEnumerable<float> source)
2187 if (source == null) throw new ArgumentNullException("source");
2190 foreach (var num in source)
2191 sum = checked(sum + num);
2197 /// Computes the sum of a sequence of nullable <see cref="System.Single" />
2198 /// values that are obtained by invoking a transform function on
2199 /// each element of the input sequence.
2202 public static float Sum<TSource>(
2203 this IEnumerable<TSource> source,
2204 Func<TSource, float> selector)
2206 return source.Select(selector).Sum();
2210 /// Computes the average of a sequence of nullable <see cref="System.Single" /> values.
2213 public static float Average(
2214 this IEnumerable<float> source)
2216 if (source == null) throw new ArgumentNullException("source");
2221 foreach (var num in source)
2229 throw new InvalidOperationException();
2231 return (float) sum / count;
2235 /// Computes the average of a sequence of nullable <see cref="System.Single" /> values
2236 /// that are obtained by invoking a transform function on each
2237 /// element of the input sequence.
2240 public static float Average<TSource>(
2241 this IEnumerable<TSource> source,
2242 Func<TSource, float> selector)
2244 return source.Select(selector).Average();
2249 /// Computes the sum of a sequence of <see cref="System.Single" /> values.
2252 public static float? Sum(
2253 this IEnumerable<float?> source)
2255 if (source == null) throw new ArgumentNullException("source");
2258 foreach (var num in source)
2259 sum = checked(sum + (num ?? 0));
2265 /// Computes the sum of a sequence of <see cref="System.Single" />
2266 /// values that are obtained by invoking a transform function on
2267 /// each element of the input sequence.
2270 public static float? Sum<TSource>(
2271 this IEnumerable<TSource> source,
2272 Func<TSource, float?> selector)
2274 return source.Select(selector).Sum();
2278 /// Computes the average of a sequence of <see cref="System.Single" /> values.
2281 public static float? Average(
2282 this IEnumerable<float?> source)
2284 if (source == null) throw new ArgumentNullException("source");
2289 foreach (var num in source.Where(n => n != null))
2299 return (float?) sum / count;
2303 /// Computes the average of a sequence of <see cref="System.Single" /> values
2304 /// that are obtained by invoking a transform function on each
2305 /// element of the input sequence.
2308 public static float? Average<TSource>(
2309 this IEnumerable<TSource> source,
2310 Func<TSource, float?> selector)
2312 return source.Select(selector).Average();
2316 /// Returns the minimum value in a sequence of nullable
2317 /// <see cref="System.Single" /> values.
2320 public static float? Min(
2321 this IEnumerable<float?> source)
2323 if (source == null) throw new ArgumentNullException("source");
2325 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
2329 /// Invokes a transform function on each element of a sequence and
2330 /// returns the minimum nullable <see cref="System.Single" /> value.
2333 public static float? Min<TSource>(
2334 this IEnumerable<TSource> source,
2335 Func<TSource, float?> selector)
2337 return source.Select(selector).Min();
2341 /// Returns the maximum value in a sequence of nullable
2342 /// <see cref="System.Single" /> values.
2345 public static float? Max(
2346 this IEnumerable<float?> source)
2348 if (source == null) throw new ArgumentNullException("source");
2350 return MinMaxImpl(source.Where(x => x != null),
2351 null, (max, x) => x == null || (max != null && x.Value < max.Value));
2355 /// Invokes a transform function on each element of a sequence and
2356 /// returns the maximum nullable <see cref="System.Single" /> value.
2359 public static float? Max<TSource>(
2360 this IEnumerable<TSource> source,
2361 Func<TSource, float?> selector)
2363 return source.Select(selector).Max();
2367 /// Computes the sum of a sequence of nullable <see cref="System.Double" /> values.
2370 public static double Sum(
2371 this IEnumerable<double> source)
2373 if (source == null) throw new ArgumentNullException("source");
2376 foreach (var num in source)
2377 sum = checked(sum + num);
2383 /// Computes the sum of a sequence of nullable <see cref="System.Double" />
2384 /// values that are obtained by invoking a transform function on
2385 /// each element of the input sequence.
2388 public static double Sum<TSource>(
2389 this IEnumerable<TSource> source,
2390 Func<TSource, double> selector)
2392 return source.Select(selector).Sum();
2396 /// Computes the average of a sequence of nullable <see cref="System.Double" /> values.
2399 public static double Average(
2400 this IEnumerable<double> source)
2402 if (source == null) throw new ArgumentNullException("source");
2407 foreach (var num in source)
2410 sum += (double) num;
2415 throw new InvalidOperationException();
2417 return (double) sum / count;
2421 /// Computes the average of a sequence of nullable <see cref="System.Double" /> values
2422 /// that are obtained by invoking a transform function on each
2423 /// element of the input sequence.
2426 public static double Average<TSource>(
2427 this IEnumerable<TSource> source,
2428 Func<TSource, double> selector)
2430 return source.Select(selector).Average();
2435 /// Computes the sum of a sequence of <see cref="System.Double" /> values.
2438 public static double? Sum(
2439 this IEnumerable<double?> source)
2441 if (source == null) throw new ArgumentNullException("source");
2444 foreach (var num in source)
2445 sum = checked(sum + (num ?? 0));
2451 /// Computes the sum of a sequence of <see cref="System.Double" />
2452 /// values that are obtained by invoking a transform function on
2453 /// each element of the input sequence.
2456 public static double? Sum<TSource>(
2457 this IEnumerable<TSource> source,
2458 Func<TSource, double?> selector)
2460 return source.Select(selector).Sum();
2464 /// Computes the average of a sequence of <see cref="System.Double" /> values.
2467 public static double? Average(
2468 this IEnumerable<double?> source)
2470 if (source == null) throw new ArgumentNullException("source");
2475 foreach (var num in source.Where(n => n != null))
2478 sum += (double) num;
2485 return (double?) sum / count;
2489 /// Computes the average of a sequence of <see cref="System.Double" /> values
2490 /// that are obtained by invoking a transform function on each
2491 /// element of the input sequence.
2494 public static double? Average<TSource>(
2495 this IEnumerable<TSource> source,
2496 Func<TSource, double?> selector)
2498 return source.Select(selector).Average();
2502 /// Returns the minimum value in a sequence of nullable
2503 /// <see cref="System.Double" /> values.
2506 public static double? Min(
2507 this IEnumerable<double?> source)
2509 if (source == null) throw new ArgumentNullException("source");
2511 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
2515 /// Invokes a transform function on each element of a sequence and
2516 /// returns the minimum nullable <see cref="System.Double" /> value.
2519 public static double? Min<TSource>(
2520 this IEnumerable<TSource> source,
2521 Func<TSource, double?> selector)
2523 return source.Select(selector).Min();
2527 /// Returns the maximum value in a sequence of nullable
2528 /// <see cref="System.Double" /> values.
2531 public static double? Max(
2532 this IEnumerable<double?> source)
2534 if (source == null) throw new ArgumentNullException("source");
2536 return MinMaxImpl(source.Where(x => x != null),
2537 null, (max, x) => x == null || (max != null && x.Value < max.Value));
2541 /// Invokes a transform function on each element of a sequence and
2542 /// returns the maximum nullable <see cref="System.Double" /> value.
2545 public static double? Max<TSource>(
2546 this IEnumerable<TSource> source,
2547 Func<TSource, double?> selector)
2549 return source.Select(selector).Max();
2553 /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> values.
2556 public static decimal Sum(
2557 this IEnumerable<decimal> source)
2559 if (source == null) throw new ArgumentNullException("source");
2562 foreach (var num in source)
2563 sum = checked(sum + num);
2569 /// Computes the sum of a sequence of nullable <see cref="System.Decimal" />
2570 /// values that are obtained by invoking a transform function on
2571 /// each element of the input sequence.
2574 public static decimal Sum<TSource>(
2575 this IEnumerable<TSource> source,
2576 Func<TSource, decimal> selector)
2578 return source.Select(selector).Sum();
2582 /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values.
2585 public static decimal Average(
2586 this IEnumerable<decimal> source)
2588 if (source == null) throw new ArgumentNullException("source");
2593 foreach (var num in source)
2596 sum += (decimal) num;
2601 throw new InvalidOperationException();
2603 return (decimal) sum / count;
2607 /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values
2608 /// that are obtained by invoking a transform function on each
2609 /// element of the input sequence.
2612 public static decimal Average<TSource>(
2613 this IEnumerable<TSource> source,
2614 Func<TSource, decimal> selector)
2616 return source.Select(selector).Average();
2621 /// Computes the sum of a sequence of <see cref="System.Decimal" /> values.
2624 public static decimal? Sum(
2625 this IEnumerable<decimal?> source)
2627 if (source == null) throw new ArgumentNullException("source");
2630 foreach (var num in source)
2631 sum = checked(sum + (num ?? 0));
2637 /// Computes the sum of a sequence of <see cref="System.Decimal" />
2638 /// values that are obtained by invoking a transform function on
2639 /// each element of the input sequence.
2642 public static decimal? Sum<TSource>(
2643 this IEnumerable<TSource> source,
2644 Func<TSource, decimal?> selector)
2646 return source.Select(selector).Sum();
2650 /// Computes the average of a sequence of <see cref="System.Decimal" /> values.
2653 public static decimal? Average(
2654 this IEnumerable<decimal?> source)
2656 if (source == null) throw new ArgumentNullException("source");
2661 foreach (var num in source.Where(n => n != null))
2664 sum += (decimal) num;
2671 return (decimal?) sum / count;
2675 /// Computes the average of a sequence of <see cref="System.Decimal" /> values
2676 /// that are obtained by invoking a transform function on each
2677 /// element of the input sequence.
2680 public static decimal? Average<TSource>(
2681 this IEnumerable<TSource> source,
2682 Func<TSource, decimal?> selector)
2684 return source.Select(selector).Average();
2688 /// Returns the minimum value in a sequence of nullable
2689 /// <see cref="System.Decimal" /> values.
2692 public static decimal? Min(
2693 this IEnumerable<decimal?> source)
2695 if (source == null) throw new ArgumentNullException("source");
2697 return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
2701 /// Invokes a transform function on each element of a sequence and
2702 /// returns the minimum nullable <see cref="System.Decimal" /> value.
2705 public static decimal? Min<TSource>(
2706 this IEnumerable<TSource> source,
2707 Func<TSource, decimal?> selector)
2709 return source.Select(selector).Min();
2713 /// Returns the maximum value in a sequence of nullable
2714 /// <see cref="System.Decimal" /> values.
2717 public static decimal? Max(
2718 this IEnumerable<decimal?> source)
2720 if (source == null) throw new ArgumentNullException("source");
2722 return MinMaxImpl(source.Where(x => x != null),
2723 null, (max, x) => x == null || (max != null && x.Value < max.Value));
2727 /// Invokes a transform function on each element of a sequence and
2728 /// returns the maximum nullable <see cref="System.Decimal" /> value.
2731 public static decimal? Max<TSource>(
2732 this IEnumerable<TSource> source,
2733 Func<TSource, decimal?> selector)
2735 return source.Select(selector).Max();
2740 // $Id: ExtensionAttribute.cs 898b3d493ed6 2012/04/17 20:09:57 azizatif $
2742 namespace System.Runtime.CompilerServices
2745 /// This attribute allows us to define extension methods without
2746 /// requiring .NET Framework 3.5. For more information, see the section,
2747 /// <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>,
2748 /// of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a>
2749 /// column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>,
2750 /// issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>.
2753 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
2754 sealed partial class ExtensionAttribute : Attribute { }
2757 // $Id: Func.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
2762 public delegate TResult Func<out TResult>();
2763 public delegate TResult Func<in T, out TResult>(T a);
2764 public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
2765 public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
2766 public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
2768 delegate TResult Func<TResult>();
2769 delegate TResult Func<T, TResult>(T a);
2770 delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
2771 delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
2772 delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
2776 // $Id: IGrouping.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
2778 namespace System.Linq
2782 using System.Collections.Generic;
2787 /// Represents a collection of objects that have a common key.
2790 partial interface IGrouping<out TKey, TElement> : IEnumerable<TElement>
2793 /// Gets the key of the <see cref="IGrouping{TKey,TElement}" />.
2800 // $Id: ILookup.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
2802 namespace System.Linq
2804 using System.Collections.Generic;
2807 /// Defines an indexer, size property, and Boolean search method for
2808 /// data structures that map keys to <see cref="IEnumerable{T}"/>
2809 /// sequences of values.
2812 partial interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>
2814 bool Contains(TKey key);
2816 IEnumerable<TElement> this[TKey key] { get; }
2820 // $Id: Internal.cs 1567e00f1a20 2012/04/17 16:09:51 azizatif $
2822 namespace LinqBridge
2827 using System.Collections.Generic;
2832 /// This type is not intended to be used directly from user code.
2833 /// It may be removed or changed in a future version without notice.
2836 sealed class DelegatingComparer<T> : IComparer<T>
2838 private readonly Func<T, T, int> _comparer;
2840 public DelegatingComparer(Func<T, T, int> comparer)
2842 if (comparer == null) throw new ArgumentNullException("comparer");
2843 _comparer = comparer;
2846 public int Compare(T x, T y) { return _comparer(x, y); }
2850 /// This type is not intended to be used directly from user code.
2851 /// It may be removed or changed in a future version without notice.
2856 public Key(T value) : this() { Value = value; }
2857 public T Value { get; private set; }
2861 /// This type is not intended to be used directly from user code.
2862 /// It may be removed or changed in a future version without notice.
2865 sealed class KeyComparer<T> : IEqualityComparer<Key<T>>
2867 private readonly IEqualityComparer<T> _innerComparer;
2869 public KeyComparer(IEqualityComparer<T> innerComparer)
2871 _innerComparer = innerComparer ?? EqualityComparer<T>.Default;
2874 public bool Equals(Key<T> x, Key<T> y)
2876 return _innerComparer.Equals(x.Value, y.Value);
2879 public int GetHashCode(Key<T> obj)
2881 return obj.Value == null ? 0 : _innerComparer.GetHashCode(obj.Value);
2886 // $Id: IOrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
2888 namespace System.Linq
2890 using System.Collections.Generic;
2893 /// Represents a sorted sequence.
2896 partial interface IOrderedEnumerable<TElement> : IEnumerable<TElement>
2899 /// Performs a subsequent ordering on the elements of an
2900 /// <see cref="IOrderedEnumerable{T}"/> according to a key.
2903 IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(
2904 Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
2908 // $Id: Lookup.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
2910 namespace System.Linq
2915 using System.Collections;
2916 using System.Collections.Generic;
2917 using IEnumerable=System.Collections.IEnumerable;
2923 /// Represents a collection of keys each mapped to one or more values.
2926 internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
2928 private readonly Dictionary<Key<TKey>, IGrouping<TKey, TElement>> _map;
2929 private readonly List<Key<TKey>> _orderedKeys; // remember order of insertion
2931 internal Lookup(IEqualityComparer<TKey> comparer)
2933 _map = new Dictionary<Key<TKey>, IGrouping<TKey, TElement>>(new KeyComparer<TKey>(comparer));
2934 _orderedKeys = new List<Key<TKey>>();
2937 internal void Add(IGrouping<TKey, TElement> item)
2939 var key = new Key<TKey>(item.Key);
2940 _map.Add(key, item);
2941 _orderedKeys.Add(key);
2944 internal IEnumerable<TElement> Find(TKey key)
2946 IGrouping<TKey, TElement> grouping;
2947 return _map.TryGetValue(new Key<TKey>(key), out grouping) ? grouping : null;
2951 /// Gets the number of key/value collection pairs in the <see cref="Lookup{TKey,TElement}" />.
2956 get { return _map.Count; }
2960 /// Gets the collection of values indexed by the specified key.
2963 public IEnumerable<TElement> this[TKey key]
2967 IGrouping<TKey, TElement> result;
2968 return _map.TryGetValue(new Key<TKey>(key), out result) ? result : Enumerable.Empty<TElement>();
2973 /// Determines whether a specified key is in the <see cref="Lookup{TKey,TElement}" />.
2976 public bool Contains(TKey key)
2978 return _map.ContainsKey(new Key<TKey>(key));
2982 /// Applies a transform function to each key and its associated
2983 /// values and returns the results.
2986 public IEnumerable<TResult> ApplyResultSelector<TResult>(
2987 Func<TKey, IEnumerable<TElement>, TResult> resultSelector)
2989 if (resultSelector == null)
2990 throw new ArgumentNullException("resultSelector");
2992 foreach (var pair in _map)
2993 yield return resultSelector(pair.Key.Value, pair.Value);
2997 /// Returns a generic enumerator that iterates through the <see cref="Lookup{TKey,TElement}" />.
3000 public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
3002 foreach (var key in _orderedKeys)
3003 yield return _map[key];
3006 IEnumerator IEnumerable.GetEnumerator()
3008 return GetEnumerator();
3013 // $Id: OrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
3015 namespace LinqBridge
3020 using System.Collections;
3021 using System.Collections.Generic;
3022 using System.Diagnostics;
3027 internal sealed class OrderedEnumerable<T, K> : IOrderedEnumerable<T>
3029 private readonly IEnumerable<T> _source;
3030 private readonly Func<T[], IComparer<int>, IComparer<int>> _comparerComposer;
3032 public OrderedEnumerable(IEnumerable<T> source,
3033 Func<T, K> keySelector, IComparer<K> comparer, bool descending) :
3034 this(source, (_, next) => next, keySelector, comparer, descending) {}
3036 private OrderedEnumerable(IEnumerable<T> source,
3037 Func<T[], IComparer<int>, IComparer<int>> parent,
3038 Func<T, K> keySelector, IComparer<K> comparer, bool descending)
3040 if (source == null) throw new ArgumentNullException("source");
3041 if (keySelector == null) throw new ArgumentNullException("keySelector");
3042 Debug.Assert(parent != null);
3046 comparer = comparer ?? Comparer<K>.Default;
3047 var direction = descending ? -1 : 1;
3049 _comparerComposer = (items, next) =>
3051 Debug.Assert(items != null);
3052 Debug.Assert(next != null);
3054 var keys = new K[items.Length];
3055 for (var i = 0; i < items.Length; i++)
3056 keys[i] = keySelector(items[i]);
3058 return parent(items, new DelegatingComparer<int>((i, j) =>
3060 var result = direction * comparer.Compare(keys[i], keys[j]);
3061 return result != 0 ? result : next.Compare(i, j);
3066 public IOrderedEnumerable<T> CreateOrderedEnumerable<KK>(
3067 Func<T, KK> keySelector, IComparer<KK> comparer, bool descending)
3069 return new OrderedEnumerable<T, KK>(_source, _comparerComposer, keySelector, comparer, descending);
3072 public IEnumerator<T> GetEnumerator()
3075 // Sort using Array.Sort but docs say that it performs an
3076 // unstable sort. LINQ, on the other hand, says OrderBy performs
3077 // a stable sort. Use the item position then as a tie
3078 // breaker when all keys compare equal, thus making the sort
3082 var items = _source.ToArray();
3083 var positionComparer = new DelegatingComparer<int>((i, j) => i.CompareTo(j));
3084 var comparer = _comparerComposer(items, positionComparer);
3085 var keys = new int[items.Length];
3086 for (var i = 0; i < keys.Length; i++)
3088 Array.Sort(keys, items, comparer);
3089 return ((IEnumerable<T>) items).GetEnumerator();
3092 IEnumerator IEnumerable.GetEnumerator()
3094 return GetEnumerator();
3099 // $Id: Action.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
3104 public delegate void Action();
3105 public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
3106 public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
3107 public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
3109 delegate void Action();
3110 delegate void Action<T1, T2>(T1 arg1, T2 arg2);
3111 delegate void Action<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
3112 delegate void Action<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);