2007-03-29 Miguel de Icaza <miguel@novell.com>
[mono.git] / mcs / class / System.Core / System.Linq / Enumerable.cs
1 // Permission is hereby granted, free of charge, to any person obtaining\r
2 // a copy of this software and associated documentation files (the\r
3 // "Software"), to deal in the Software without restriction, including\r
4 // without limitation the rights to use, copy, modify, merge, publish,\r
5 // distribute, sublicense, and/or sell copies of the Software, and to\r
6 // permit persons to whom the Software is furnished to do so, subject to\r
7 // the following conditions:\r
8 // \r
9 // The above copyright notice and this permission notice shall be\r
10 // included in all copies or substantial portions of the Software.\r
11 // \r
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
18 //\r
19 // Authors:\r
20 //        Marek Safar (marek.safar@gmail.com)\r
21 //        Antonello Provenzano  <antonello@deveel.com>\r
22 //        Alejandro Serrano "Serras" (trupill@yahoo.es)\r
23 //\r
24 \r
25 using System;\r
26 using System.Collections;\r
27 using System.Collections.Generic;\r
28 using System.Collections.ObjectModel;\r
29 \r
30 namespace System.Linq\r
31 {\r
32     public static class Enumerable\r
33     {\r
34         #region Aggregate\r
35         public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)\r
36         {\r
37             if (source == null || func == null)\r
38                 throw new ArgumentNullException();\r
39 \r
40             int counter = 0;\r
41             TSource folded = default(TSource);\r
42 \r
43             foreach (TSource element in source)\r
44             {\r
45                 if (counter == 0)\r
46                     folded = element;\r
47                 else\r
48                     folded = func(folded, element);\r
49             }\r
50 \r
51             if (counter == 0)\r
52                 throw new InvalidOperationException();\r
53             else\r
54                 return folded;\r
55         }\r
56 \r
57 \r
58         public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source,\r
59             TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)\r
60         {\r
61             if (source == null || func == null)\r
62                 throw new ArgumentNullException();\r
63 \r
64             TAccumulate folded = seed;\r
65             foreach (TSource element in source)\r
66                 folded = func(folded, element);\r
67             return folded;\r
68         }\r
69 \r
70 \r
71         public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector)\r
72         {\r
73             if (source == null)\r
74                 throw new ArgumentNullException("source");\r
75             if (func == null)\r
76                 throw new ArgumentNullException("func");\r
77             if (resultSelector == null)\r
78                 throw new ArgumentNullException("resultSelector");\r
79 \r
80             TAccumulate result = seed;\r
81             foreach (TSource e in source)\r
82                 result = func(result, e);\r
83             return resultSelector(result);\r
84         }\r
85         #endregion\r
86 \r
87         #region All\r
88         public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)\r
89         {\r
90             if (source == null || predicate == null)\r
91                 throw new ArgumentNullException();\r
92 \r
93             foreach (TSource element in source)\r
94                 if (!predicate(element))\r
95                     return false;\r
96             return true;\r
97         }\r
98         #endregion\r
99 \r
100         #region Any\r
101         public static bool Any<TSource>(this IEnumerable<TSource> source)\r
102         {\r
103             if (source == null)\r
104                 throw new ArgumentNullException();\r
105 \r
106             foreach (TSource element in source)\r
107                 return true;\r
108             return false;\r
109         }\r
110 \r
111 \r
112         public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)\r
113         {\r
114             if (source == null || predicate == null)\r
115                 throw new ArgumentNullException();\r
116 \r
117             foreach (TSource element in source)\r
118                 if (predicate(element))\r
119                     return true;\r
120             return false;\r
121         }\r
122         #endregion\r
123 \r
124         #region AsEnumerable\r
125         public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)\r
126         {\r
127             return source;\r
128         }\r
129         #endregion\r
130 \r
131         #region Average\r
132         public static double Average(this IEnumerable<int> source)\r
133         {\r
134             if (source == null)\r
135                 throw new ArgumentNullException();\r
136 \r
137             long sum = 0;\r
138             long counter = 0;\r
139             foreach (int element in source)\r
140             {\r
141                 sum += element;\r
142                 counter++;\r
143             }\r
144 \r
145             if (counter == 0)\r
146                 throw new InvalidOperationException();\r
147             else\r
148                 return (double)sum / (double)counter;\r
149         }\r
150 \r
151 \r
152         public static double? Average(this IEnumerable<int?> source)\r
153         {\r
154             if (source == null)\r
155                 throw new ArgumentNullException();\r
156 \r
157             bool onlyNull = true;\r
158             long sum = 0;\r
159             long counter = 0;\r
160             foreach (int? element in source)\r
161             {\r
162                 if (element.HasValue)\r
163                 {\r
164                     onlyNull = false;\r
165                     sum += element.Value;\r
166                     counter++;\r
167                 }\r
168             }\r
169             return (onlyNull ? null : (double?)sum / (double?)counter);\r
170         }\r
171 \r
172 \r
173         public static double Average(this IEnumerable<long> source)\r
174         {\r
175             if (source == null)\r
176                 throw new ArgumentNullException();\r
177 \r
178             long sum = 0;\r
179             long counter = 0;\r
180             foreach (long element in source)\r
181             {\r
182                 sum += element;\r
183                 counter++;\r
184             }\r
185 \r
186             if (counter == 0)\r
187                 throw new InvalidOperationException();\r
188             else\r
189                 return (double)sum / (double)counter;\r
190         }\r
191 \r
192 \r
193         public static double? Average(this IEnumerable<long?> source)\r
194         {\r
195             if (source == null)\r
196                 throw new ArgumentNullException();\r
197 \r
198             bool onlyNull = true;\r
199             long sum = 0;\r
200             long counter = 0;\r
201             foreach (long? element in source)\r
202             {\r
203                 if (element.HasValue)\r
204                 {\r
205                     onlyNull = false;\r
206                     sum += element.Value;\r
207                     counter++;\r
208                 }\r
209             }\r
210             return (onlyNull ? null : (double?)sum / (double?)counter);\r
211         }\r
212 \r
213 \r
214         public static double Average(this IEnumerable<double> source)\r
215         {\r
216             if (source == null)\r
217                 throw new ArgumentNullException();\r
218 \r
219             double sum = 0;\r
220             double counter = 0;\r
221             foreach (double element in source)\r
222             {\r
223                 sum += element;\r
224                 counter++;\r
225             }\r
226 \r
227             if (counter == 0)\r
228                 throw new InvalidOperationException();\r
229             else\r
230                 return sum / counter;\r
231         }\r
232 \r
233 \r
234         public static double? Average(this IEnumerable<double?> source)\r
235         {\r
236             if (source == null)\r
237                 throw new ArgumentNullException();\r
238 \r
239             bool onlyNull = true;\r
240             double sum = 0;\r
241             double counter = 0;\r
242             foreach (double? element in source)\r
243             {\r
244                 if (element.HasValue)\r
245                 {\r
246                     onlyNull = false;\r
247                     sum += element.Value;\r
248                     counter++;\r
249                 }\r
250             }\r
251             return (onlyNull ? null : (double?)(sum / counter));\r
252         }\r
253 \r
254 \r
255         public static decimal Average(this IEnumerable<decimal> source)\r
256         {\r
257             if (source == null)\r
258                 throw new ArgumentNullException();\r
259 \r
260             decimal sum = 0;\r
261             decimal counter = 0;\r
262             foreach (decimal element in source)\r
263             {\r
264                 sum += element;\r
265                 counter++;\r
266             }\r
267 \r
268             if (counter == 0)\r
269                 throw new InvalidOperationException();\r
270             else\r
271                 return sum / counter;\r
272         }\r
273 \r
274 \r
275         public static decimal? Average(this IEnumerable<decimal?> source)\r
276         {\r
277             if (source == null)\r
278                 throw new ArgumentNullException();\r
279 \r
280             bool onlyNull = true;\r
281             decimal sum = 0;\r
282             decimal counter = 0;\r
283             foreach (decimal? element in source)\r
284             {\r
285                 if (element.HasValue)\r
286                 {\r
287                     onlyNull = false;\r
288                     sum += element.Value;\r
289                     counter++;\r
290                 }\r
291             }\r
292             return (onlyNull ? null : (decimal?)(sum / counter));\r
293         }\r
294 \r
295 \r
296         public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)\r
297         {\r
298             if (source == null || selector == null)\r
299                 throw new ArgumentNullException();\r
300 \r
301             long sum = 0;\r
302             long counter = 0;\r
303             foreach (TSource item in source)\r
304             {\r
305                 sum += selector(item);\r
306                 counter++;\r
307             }\r
308 \r
309             if (counter == 0)\r
310                 throw new InvalidOperationException();\r
311             else\r
312                 return (double)sum / (double)counter;\r
313         }\r
314 \r
315 \r
316         public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)\r
317         {\r
318             if (source == null || selector == null)\r
319                 throw new ArgumentNullException();\r
320 \r
321             bool onlyNull = true;\r
322             long sum = 0;\r
323             long counter = 0;\r
324             foreach (TSource item in source)\r
325             {\r
326                 int? element = selector(item);\r
327                 if (element.HasValue)\r
328                 {\r
329                     onlyNull = false;\r
330                     sum += element.Value;\r
331                     counter++;\r
332                 }\r
333             }\r
334             return (onlyNull ? null : (double?)sum / (double?)counter);\r
335         }\r
336 \r
337 \r
338         public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)\r
339         {\r
340             if (source == null || selector == null)\r
341                 throw new ArgumentNullException();\r
342 \r
343             long sum = 0;\r
344             long counter = 0;\r
345             foreach (TSource item in source)\r
346             {\r
347                 sum += selector(item);\r
348                 counter++;\r
349             }\r
350 \r
351             if (counter == 0)\r
352                 throw new InvalidOperationException();\r
353             else\r
354                 return (double)sum / (double)counter;\r
355         }\r
356 \r
357 \r
358         public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)\r
359         {\r
360             if (source == null || selector == null)\r
361                 throw new ArgumentNullException();\r
362 \r
363             bool onlyNull = true;\r
364             long sum = 0;\r
365             long counter = 0;\r
366             foreach (TSource item in source)\r
367             {\r
368                 long? element = selector(item);\r
369                 if (element.HasValue)\r
370                 {\r
371                     onlyNull = false;\r
372                     sum += element.Value;\r
373                     counter++;\r
374                 }\r
375             }\r
376             return (onlyNull ? null : (double?)sum / (double?)counter);\r
377         }\r
378 \r
379 \r
380         public static double Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)\r
381         {\r
382             if (source == null || selector == null)\r
383                 throw new ArgumentNullException();\r
384 \r
385             double sum = 0;\r
386             double counter = 0;\r
387             foreach (TSource item in source)\r
388             {\r
389                 sum += selector(item);\r
390                 counter++;\r
391             }\r
392 \r
393             if (counter == 0)\r
394                 throw new InvalidOperationException();\r
395             else\r
396                 return sum / counter;\r
397         }\r
398 \r
399 \r
400         public static double? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)\r
401         {\r
402             if (source == null || selector == null)\r
403                 throw new ArgumentNullException();\r
404 \r
405             bool onlyNull = true;\r
406             double sum = 0;\r
407             double counter = 0;\r
408             foreach (TSource item in source)\r
409             {\r
410                 double? element = selector(item);\r
411                 if (element.HasValue)\r
412                 {\r
413                     onlyNull = false;\r
414                     sum += element.Value;\r
415                     counter++;\r
416                 }\r
417             }\r
418             return (onlyNull ? null : (double?)(sum / counter));\r
419         }\r
420 \r
421 \r
422         public static decimal Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)\r
423         {\r
424             if (source == null || selector == null)\r
425                 throw new ArgumentNullException();\r
426 \r
427             decimal sum = 0;\r
428             decimal counter = 0;\r
429             foreach (TSource item in source)\r
430             {\r
431                 sum += selector(item);\r
432                 counter++;\r
433             }\r
434 \r
435             if (counter == 0)\r
436                 throw new InvalidOperationException();\r
437             else\r
438                 return sum / counter;\r
439         }\r
440 \r
441 \r
442         public static decimal? Average<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)\r
443         {\r
444             if (source == null || selector == null)\r
445                 throw new ArgumentNullException();\r
446 \r
447             bool onlyNull = true;\r
448             decimal sum = 0;\r
449             decimal counter = 0;\r
450             foreach (TSource item in source)\r
451             {\r
452                 decimal? element = selector(item);\r
453                 if (element.HasValue)\r
454                 {\r
455                     onlyNull = false;\r
456                     sum += element.Value;\r
457                     counter++;\r
458                 }\r
459             }\r
460             return (onlyNull ? null : (decimal?)(sum / counter));\r
461         }\r
462         #endregion\r
463 \r
464         #region Cast\r
465         public static IEnumerable<TSource> Cast<TSource>(this IEnumerable source)\r
466         {\r
467             if (source == null)\r
468                 throw new ArgumentNullException();\r
469 \r
470             foreach (object element in source)\r
471                 yield return (TSource)element;\r
472         }\r
473         #endregion\r
474 \r
475         #region Concat\r
476         public static IEnumerable<TSource> Concat<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)\r
477         {\r
478             if (first == null || second == null)\r
479                 throw new ArgumentNullException();\r
480 \r
481             foreach (TSource element in first)\r
482                 yield return element;\r
483             foreach (TSource element in second)\r
484                 yield return element;\r
485         }\r
486 \r
487         #endregion\r
488 \r
489         #region Contains\r
490 \r
491         public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value)\r
492         {\r
493             if (source is ICollection<TSource>)\r
494             {\r
495                 ICollection<TSource> collection = (ICollection<TSource>)source;\r
496                 return collection.Contains(value);\r
497             }\r
498 \r
499             return Contains<TSource>(source, value, null);\r
500         }\r
501 \r
502 \r
503         public static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value, IEqualityComparer<TSource> comparer)\r
504         {\r
505             if (source == null)\r
506                 throw new ArgumentNullException("source");\r
507 \r
508             if (comparer == null)\r
509                 comparer = EqualityComparer<TSource>.Default;\r
510 \r
511 \r
512             foreach (TSource e in source)\r
513             {\r
514                 if (comparer.Equals(e, value))\r
515                     return true;\r
516             }\r
517 \r
518             return false;\r
519         }\r
520         #endregion\r
521 \r
522         #region Count\r
523         public static int Count<TSource>(this IEnumerable<TSource> source)\r
524         {\r
525             if (source == null)\r
526                 throw new ArgumentNullException();\r
527 \r
528             if (source is ICollection<TSource>)\r
529                 return ((ICollection<TSource>)source).Count;\r
530             else\r
531             {\r
532                 int counter = 0;\r
533                 foreach (TSource element in source)\r
534                     counter++;\r
535                 return counter;\r
536             }\r
537         }\r
538 \r
539 \r
540         public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> selector)\r
541         {\r
542             if (source == null || selector == null)\r
543                 throw new ArgumentNullException();\r
544 \r
545             int counter = 0;\r
546             foreach (TSource element in source)\r
547                 if (selector(element))\r
548                     counter++;\r
549 \r
550             return counter;\r
551         }\r
552         #endregion\r
553 \r
554         #region DefaultIfEmpty\r
555 \r
556         public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source)\r
557         {\r
558             if (source == null)\r
559                 throw new ArgumentNullException();\r
560 \r
561             bool noYield = true;\r
562             foreach (TSource item in source)\r
563             {\r
564                 noYield = false;\r
565                 yield return item;\r
566             }\r
567 \r
568             if (noYield)\r
569                 yield return default(TSource);\r
570         }\r
571 \r
572 \r
573         public static IEnumerable<TSource> DefaultIfEmpty<TSource>(this IEnumerable<TSource> source, TSource defaultValue)\r
574         {\r
575             if (source == null)\r
576                 throw new ArgumentNullException();\r
577 \r
578             bool noYield = true;\r
579             foreach (TSource item in source)\r
580             {\r
581                 noYield = false;\r
582                 yield return item;\r
583             }\r
584 \r
585             if (noYield)\r
586                 yield return defaultValue;\r
587         }\r
588 \r
589         #endregion\r
590 \r
591         #region Distinct\r
592 \r
593         public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source)\r
594         {\r
595             return Distinct<TSource>(source, null);\r
596         }\r
597 \r
598         public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)\r
599         {\r
600             if (source == null)\r
601                 throw new ArgumentNullException();\r
602 \r
603             if (comparer == null)\r
604                 comparer = EqualityComparer<TSource>.Default;\r
605 \r
606             List<TSource> items = new List<TSource>();\r
607             foreach (TSource element in source)\r
608             {\r
609                 if (!Contains (items, element, comparer))\r
610                 {\r
611                     items.Add(element);\r
612                     yield return element;\r
613                 }\r
614             }\r
615         }\r
616         #endregion\r
617 \r
618         #region ElementAt\r
619 \r
620         public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)\r
621         {\r
622             if (source == null)\r
623                 throw new ArgumentNullException();\r
624             if (index < 0)\r
625                 throw new ArgumentOutOfRangeException();\r
626 \r
627             if (source is IList<TSource>)\r
628                 return ((IList<TSource>)source)[index];\r
629             else\r
630             {\r
631                 int counter = 0;\r
632                 foreach (TSource element in source)\r
633                 {\r
634                     if (counter == index)\r
635                         return element;\r
636                     counter++;\r
637                 }\r
638                 throw new ArgumentOutOfRangeException();\r
639             }\r
640         }\r
641 \r
642         #endregion\r
643 \r
644         #region ElementAtOrDefault\r
645 \r
646         public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)\r
647         {\r
648             if (source == null)\r
649                 throw new ArgumentNullException();\r
650             if (index < 0)\r
651                 return default(TSource);\r
652 \r
653             if (source is IList<TSource>)\r
654             {\r
655                 if (((IList<TSource>)source).Count >= index)\r
656                     return default(TSource);\r
657                 else\r
658                     return ((IList<TSource>)source)[index];\r
659             }\r
660             else\r
661             {\r
662                 int counter = 0;\r
663                 foreach (TSource element in source)\r
664                 {\r
665                     if (counter == index)\r
666                         return element;\r
667                     counter++;\r
668                 }\r
669                 return default(TSource);\r
670             }\r
671         }\r
672 \r
673         #endregion\r
674 \r
675         #region Empty\r
676         public static IEnumerable<TResult> Empty<TResult>()\r
677         {\r
678             return new List<TResult>();\r
679         }\r
680         #endregion\r
681 \r
682         #region Except\r
683 \r
684         public static IEnumerable<T> Except<T>(this IEnumerable<T> first, IEnumerable<T> second)\r
685         {\r
686             return Except<T>(first, second, null);\r
687         }\r
688 \r
689         public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer)\r
690         {\r
691             if (first == null || second == null)\r
692                 throw new ArgumentNullException();\r
693 \r
694             if (comparer == null)\r
695                 comparer = EqualityComparer<TSource>.Default;\r
696 \r
697             List<TSource> items = new List<TSource>(Distinct(first));\r
698             foreach (TSource element in second)\r
699             {\r
700                 int index = IndexOf(items, element, comparer);\r
701                 if (index == -1)\r
702                     items.Add(element);\r
703                 else\r
704                     items.RemoveAt(index);\r
705             }\r
706             foreach (TSource item in items)\r
707                 yield return item;\r
708         }\r
709 \r
710         #endregion\r
711 \r
712         #region First\r
713 \r
714         public static TSource First<TSource>(this IEnumerable<TSource> source)\r
715         {\r
716             if (source == null)\r
717                 throw new ArgumentNullException();\r
718 \r
719             foreach (TSource element in source)\r
720                 return element;\r
721 \r
722             throw new InvalidOperationException();\r
723         }\r
724 \r
725 \r
726         public static TSource First<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)\r
727         {\r
728             if (source == null || predicate == null)\r
729                 throw new ArgumentNullException();\r
730 \r
731             foreach (TSource element in source)\r
732             {\r
733                 if (predicate(element))\r
734                     return element;\r
735             }\r
736 \r
737             throw new InvalidOperationException();\r
738         }\r
739 \r
740         #endregion\r
741 \r
742         #region FirstOrDefault\r
743 \r
744         public static T FirstOrDefault<T>(this IEnumerable<T> source)\r
745         {\r
746             if (source == null)\r
747                 throw new ArgumentNullException();\r
748 \r
749             foreach (T element in source)\r
750                 return element;\r
751 \r
752             return default(T);\r
753         }\r
754 \r
755 \r
756         public static T FirstOrDefault<T>(this IEnumerable<T> source, Func<T, bool> predicate)\r
757         {\r
758             if (source == null || predicate == null)\r
759                 throw new ArgumentNullException();\r
760 \r
761             foreach (T element in source)\r
762             {\r
763                 if (predicate(element))\r
764                     return element;\r
765             }\r
766 \r
767             return default(T);\r
768         }\r
769 \r
770         #endregion\r
771 \r
772         #region GroupBy\r
773 \r
774         private static List<T> ContainsGroup<K, T>(\r
775                 Dictionary<K, List<T>> items, K key, IEqualityComparer<K> comparer)\r
776         {\r
777             IEqualityComparer<K> comparerInUse = (comparer ?? EqualityComparer<K>.Default);\r
778             foreach (KeyValuePair<K, List<T>> value in items)\r
779             {\r
780                 if (comparerInUse.Equals(value.Key, key))\r
781                     return value.Value;\r
782             }\r
783             return null;\r
784         }\r
785 \r
786 \r
787         public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source, \r
788             Func<TSource, TKey> keySelector)\r
789         {\r
790             return GroupBy<TSource, TKey>(source, keySelector, null);\r
791         }\r
792 \r
793 \r
794         public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source,\r
795             Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)\r
796         {\r
797             if (source == null || keySelector == null)\r
798                 throw new ArgumentNullException();\r
799 \r
800             Dictionary<TKey, List<TSource>> groups = new Dictionary<TKey, List<TSource>>();\r
801             List<TSource> nullList = new List<TSource>();\r
802             int counter = 0;\r
803             int nullCounter = -1;\r
804 \r
805             foreach (TSource element in source)\r
806             {\r
807                 TKey key = keySelector(element);\r
808                 if (key == null)\r
809                 {\r
810                     nullList.Add(element);\r
811                     if (nullCounter == -1)\r
812                     {\r
813                         nullCounter = counter;\r
814                         counter++;\r
815                     }\r
816                 }\r
817                 else\r
818                 {\r
819                     List<TSource> group = ContainsGroup<TKey, TSource>(groups, key, comparer);\r
820                     if (group == null)\r
821                     {\r
822                         group = new List<TSource>();\r
823                         groups.Add(key, group);\r
824                         counter++;\r
825                     }\r
826                     group.Add(element);\r
827                 }\r
828             }\r
829 \r
830             counter = 0;\r
831             foreach (KeyValuePair<TKey, List<TSource>> group in groups)\r
832             {\r
833                 if (counter == nullCounter)\r
834                 {\r
835                     Grouping<TKey, TSource> nullGroup = new Grouping<TKey, TSource>(default(TKey), nullList);\r
836                     yield return nullGroup;\r
837                     counter++;\r
838                 }\r
839                 Grouping<TKey, TSource> grouping = new Grouping<TKey, TSource>(group.Key, group.Value);\r
840                 yield return grouping;\r
841                 counter++;\r
842             }\r
843         }\r
844 \r
845 \r
846         public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source,\r
847             Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)\r
848         {\r
849             return GroupBy<TSource, TKey, TElement>(source, keySelector, elementSelector);\r
850         }\r
851 \r
852 \r
853         public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(this IEnumerable<TSource> source,\r
854             Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)\r
855         {\r
856             if (source == null || keySelector == null || elementSelector == null)\r
857                 throw new ArgumentNullException();\r
858 \r
859             Dictionary<TKey, List<TElement>> groups = new Dictionary<TKey, List<TElement>>();\r
860             List<TElement> nullList = new List<TElement>();\r
861             int counter = 0;\r
862             int nullCounter = -1;\r
863 \r
864             foreach (TSource item in source)\r
865             {\r
866                 TKey key = keySelector(item);\r
867                 TElement element = elementSelector(item);\r
868                 if (key == null)\r
869                 {\r
870                     nullList.Add(element);\r
871                     if (nullCounter == -1)\r
872                     {\r
873                         nullCounter = counter;\r
874                         counter++;\r
875                     }\r
876                 }\r
877                 else\r
878                 {\r
879                     List<TElement> group = ContainsGroup<TKey, TElement>(groups, key, comparer);\r
880                     if (group == null)\r
881                     {\r
882                         group = new List<TElement>();\r
883                         groups.Add(key, group);\r
884                         counter++;\r
885                     }\r
886                     group.Add(element);\r
887                 }\r
888             }\r
889 \r
890             counter = 0;\r
891             foreach (KeyValuePair<TKey, List<TElement>> group in groups)\r
892             {\r
893                 if (counter == nullCounter)\r
894                 {\r
895                     Grouping<TKey, TElement> nullGroup = new Grouping<TKey, TElement>(default(TKey), nullList);\r
896                     yield return nullGroup;\r
897                     counter++;\r
898                 }\r
899                 Grouping<TKey, TElement> grouping = new Grouping<TKey, TElement>(group.Key, group.Value);\r
900                 yield return grouping;\r
901                 counter++;\r
902             }\r
903         }\r
904 \r
905         #endregion\r
906 \r
907         # region GroupJoin\r
908 \r
909         public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,\r
910             IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector, \r
911             Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector)\r
912         {\r
913             return GroupJoin(outer, inner, outerKeySelector, innerKeySelector, resultSelector, null);\r
914         }\r
915 \r
916         public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,\r
917             IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,\r
918             Func<TInner, TKey> innerKeySelector, Func<TOuter, IEnumerable<TInner>, TResult> resultSelector, \r
919             IEqualityComparer<TKey> comparer)\r
920         {\r
921             if (outer == null || inner == null || outerKeySelector == null ||\r
922                 innerKeySelector == null || resultSelector == null)\r
923                 throw new ArgumentNullException();\r
924 \r
925             if (comparer == null)\r
926                 comparer = EqualityComparer<TKey>.Default;\r
927 \r
928             Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey>(inner, innerKeySelector, comparer);\r
929             /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();\r
930             foreach (U element in inner)\r
931             {\r
932                     K innerKey = innerKeySelector (element);\r
933                     if (!innerKeys.ContainsKey (innerKey))\r
934                             innerKeys.Add (innerKey, new List<U> ());\r
935                     innerKeys[innerKey].Add (element);\r
936             }*/\r
937 \r
938             foreach (TOuter element in outer)\r
939             {\r
940                 TKey outerKey = outerKeySelector(element);\r
941                 if (innerKeys.Contains(outerKey))\r
942                     yield return resultSelector(element, innerKeys[outerKey]);\r
943             }\r
944         }\r
945 \r
946         #endregion\r
947 \r
948         #region Intersect\r
949 \r
950 \r
951         public static IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)\r
952         {\r
953             if (first == null || second == null)\r
954                 throw new ArgumentNullException();\r
955 \r
956             List<TSource> items = new List<TSource>(Distinct(first));\r
957             bool[] marked = new bool[items.Count];\r
958             for (int i = 0; i < marked.Length; i++)\r
959                 marked[i] = false;\r
960 \r
961             foreach (TSource element in second)\r
962             {\r
963                 int index = IndexOf(items, element);\r
964                 if (index != -1)\r
965                     marked[index] = true;\r
966             }\r
967             for (int i = 0; i < marked.Length; i++)\r
968             {\r
969                 if (marked[i])\r
970                     yield return items[i];\r
971             }\r
972         }\r
973 \r
974         #endregion\r
975 \r
976         # region Join\r
977 \r
978         public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,\r
979             IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,\r
980             Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector, IEqualityComparer<TKey> comparer)\r
981         {\r
982             if (outer == null || inner == null || outerKeySelector == null ||\r
983                     innerKeySelector == null || resultSelector == null)\r
984                 throw new ArgumentNullException();\r
985 \r
986             if (comparer == null)\r
987                 comparer = EqualityComparer<TKey>.Default;\r
988 \r
989             Lookup<TKey, TInner> innerKeys = ToLookup<TInner, TKey>(inner, innerKeySelector, comparer);\r
990             /*Dictionary<K, List<U>> innerKeys = new Dictionary<K, List<U>> ();\r
991             foreach (U element in inner)\r
992             {\r
993                     K innerKey = innerKeySelector (element);\r
994                     if (!innerKeys.ContainsKey (innerKey))\r
995                             innerKeys.Add (innerKey, new List<U> ());\r
996                     innerKeys[innerKey].Add (element);\r
997             }*/\r
998 \r
999             foreach (TOuter element in outer)\r
1000             {\r
1001                 TKey outerKey = outerKeySelector(element);\r
1002                 if (innerKeys.Contains(outerKey))\r
1003                 {\r
1004                     foreach (TInner innerElement in innerKeys[outerKey])\r
1005                         yield return resultSelector(element, innerElement);\r
1006                 }\r
1007             }\r
1008         }\r
1009 \r
1010         public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer,\r
1011             IEnumerable<TInner> inner, Func<TOuter, TKey> outerKeySelector,\r
1012             Func<TInner, TKey> innerKeySelector, Func<TOuter, TInner, TResult> resultSelector)\r
1013         {\r
1014             return Join<TOuter, TInner, TKey, TResult>(outer, inner, outerKeySelector, innerKeySelector, resultSelector);\r
1015         }\r
1016         # endregion\r
1017 \r
1018         #region Last\r
1019 \r
1020         public static TSource Last<TSource>(this IEnumerable<TSource> source)\r
1021         {\r
1022             if (source == null)\r
1023                 throw new ArgumentNullException();\r
1024 \r
1025             bool noElements = true;\r
1026             TSource lastElement = default(TSource);\r
1027             foreach (TSource element in source)\r
1028             {\r
1029                 if (noElements) noElements = false;\r
1030                 lastElement = element;\r
1031             }\r
1032 \r
1033             if (!noElements)\r
1034                 return lastElement;\r
1035             else\r
1036                 throw new InvalidOperationException();\r
1037         }\r
1038 \r
1039         public static TSource Last<TSource>(this IEnumerable<TSource> source,\r
1040                 Func<TSource, bool> predicate)\r
1041         {\r
1042             if (source == null || predicate == null)\r
1043                 throw new ArgumentNullException();\r
1044 \r
1045             bool noElements = true;\r
1046             TSource lastElement = default(TSource);\r
1047             foreach (TSource element in source)\r
1048             {\r
1049                 if (predicate(element))\r
1050                 {\r
1051                     if (noElements) noElements = false;\r
1052                     lastElement = element;\r
1053                 }\r
1054             }\r
1055 \r
1056             if (!noElements)\r
1057                 return lastElement;\r
1058             else\r
1059                 throw new InvalidOperationException();\r
1060         }\r
1061 \r
1062         #endregion\r
1063 \r
1064         #region LastOrDefault\r
1065 \r
1066         public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source)\r
1067         {\r
1068             if (source == null)\r
1069                 throw new ArgumentNullException();\r
1070 \r
1071             TSource lastElement = default(TSource);\r
1072             foreach (TSource element in source)\r
1073                 lastElement = element;\r
1074 \r
1075             return lastElement;\r
1076         }\r
1077 \r
1078         public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source,\r
1079             Func<TSource, bool> predicate)\r
1080         {\r
1081             if (source == null || predicate == null)\r
1082                 throw new ArgumentNullException();\r
1083 \r
1084             TSource lastElement = default(TSource);\r
1085             foreach (TSource element in source)\r
1086             {\r
1087                 if (predicate(element))\r
1088                     lastElement = element;\r
1089             }\r
1090 \r
1091             return lastElement;\r
1092         }\r
1093 \r
1094         #endregion\r
1095 \r
1096         #region LongCount\r
1097         public static long LongCount<TSource>(this IEnumerable<TSource> source)\r
1098         {\r
1099             if (source == null)\r
1100                 throw new ArgumentNullException();\r
1101 \r
1102             long counter = 0;\r
1103             foreach (TSource element in source)\r
1104                 counter++;\r
1105             return counter;\r
1106         }\r
1107 \r
1108 \r
1109         public static long LongCount<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> selector)\r
1110         {\r
1111             if (source == null || selector == null)\r
1112                 throw new ArgumentNullException();\r
1113 \r
1114             long counter = 0;\r
1115             foreach (TSource element in source)\r
1116                 if (selector(element))\r
1117                     counter++;\r
1118 \r
1119             return counter;\r
1120         }\r
1121 \r
1122         #endregion\r
1123 \r
1124         #region Max\r
1125 \r
1126         public static int Max(this IEnumerable<int> source)\r
1127         {\r
1128             if (source == null)\r
1129                 throw new ArgumentNullException();\r
1130 \r
1131             int maximum = int.MinValue;\r
1132             int counter = 0;\r
1133             foreach (int element in source)\r
1134             {\r
1135                 if (element > maximum)\r
1136                     maximum = element;\r
1137                 counter++;\r
1138             }\r
1139 \r
1140             if (counter == 0)\r
1141                 throw new InvalidOperationException();\r
1142             else\r
1143                 return maximum;\r
1144         }\r
1145 \r
1146 \r
1147         public static int? Max(this IEnumerable<int?> source)\r
1148         {\r
1149             if (source == null)\r
1150                 throw new ArgumentNullException();\r
1151 \r
1152             bool onlyNull = true;\r
1153             int? maximum = int.MinValue;\r
1154             foreach (int? element in source)\r
1155             {\r
1156                 if (element.HasValue)\r
1157                 {\r
1158                     onlyNull = false;\r
1159                     if (element > maximum)\r
1160                         maximum = element;\r
1161                 }\r
1162             }\r
1163             return (onlyNull ? null : maximum);\r
1164         }\r
1165 \r
1166 \r
1167         public static long Max(this IEnumerable<long> source)\r
1168         {\r
1169             if (source == null)\r
1170                 throw new ArgumentNullException();\r
1171 \r
1172             long maximum = long.MinValue;\r
1173             int counter = 0;\r
1174             foreach (long element in source)\r
1175             {\r
1176                 if (element > maximum)\r
1177                     maximum = element;\r
1178                 counter++;\r
1179             }\r
1180 \r
1181             if (counter == 0)\r
1182                 throw new InvalidOperationException();\r
1183             else\r
1184                 return maximum;\r
1185         }\r
1186 \r
1187 \r
1188         public static long? Max(this IEnumerable<long?> source)\r
1189         {\r
1190             if (source == null)\r
1191                 throw new ArgumentNullException();\r
1192 \r
1193             bool onlyNull = true;\r
1194             long? maximum = long.MinValue;\r
1195             foreach (long? element in source)\r
1196             {\r
1197                 if (element.HasValue)\r
1198                 {\r
1199                     onlyNull = false;\r
1200                     if (element > maximum)\r
1201                         maximum = element;\r
1202                 }\r
1203             }\r
1204             return (onlyNull ? null : maximum);\r
1205         }\r
1206 \r
1207 \r
1208         public static double Max(this IEnumerable<double> source)\r
1209         {\r
1210             if (source == null)\r
1211                 throw new ArgumentNullException();\r
1212 \r
1213             double maximum = double.MinValue;\r
1214             int counter = 0;\r
1215             foreach (double element in source)\r
1216             {\r
1217                 if (element > maximum)\r
1218                     maximum = element;\r
1219                 counter++;\r
1220             }\r
1221 \r
1222             if (counter == 0)\r
1223                 throw new InvalidOperationException();\r
1224             else\r
1225                 return maximum;\r
1226         }\r
1227 \r
1228 \r
1229         public static double? Max(this IEnumerable<double?> source)\r
1230         {\r
1231             if (source == null)\r
1232                 throw new ArgumentNullException();\r
1233 \r
1234             bool onlyNull = true;\r
1235             double? maximum = double.MinValue;\r
1236             foreach (double? element in source)\r
1237             {\r
1238                 if (element.HasValue)\r
1239                 {\r
1240                     onlyNull = false;\r
1241                     if (element > maximum)\r
1242                         maximum = element;\r
1243                 }\r
1244             }\r
1245             return (onlyNull ? null : maximum);\r
1246         }\r
1247 \r
1248 \r
1249         public static decimal Max(this IEnumerable<decimal> source)\r
1250         {\r
1251             if (source == null)\r
1252                 throw new ArgumentNullException();\r
1253 \r
1254             decimal maximum = decimal.MinValue;\r
1255             int counter = 0;\r
1256             foreach (decimal element in source)\r
1257             {\r
1258                 if (element > maximum)\r
1259                     maximum = element;\r
1260                 counter++;\r
1261             }\r
1262 \r
1263             if (counter == 0)\r
1264                 throw new InvalidOperationException();\r
1265             else\r
1266                 return maximum;\r
1267         }\r
1268 \r
1269 \r
1270         public static decimal? Max(this IEnumerable<decimal?> source)\r
1271         {\r
1272             if (source == null)\r
1273                 throw new ArgumentNullException();\r
1274 \r
1275             bool onlyNull = true;\r
1276             decimal? maximum = decimal.MinValue;\r
1277             foreach (decimal? element in source)\r
1278             {\r
1279                 if (element.HasValue)\r
1280                 {\r
1281                     onlyNull = false;\r
1282                     if (element > maximum)\r
1283                         maximum = element;\r
1284                 }\r
1285             }\r
1286             return (onlyNull ? null : maximum);\r
1287         }\r
1288 \r
1289 \r
1290         public static T Max<T>(this IEnumerable<T> source)\r
1291         {\r
1292             if (source == null)\r
1293                 throw new ArgumentNullException();\r
1294 \r
1295             bool notAssigned = true;\r
1296             T maximum = default(T);\r
1297             int counter = 0;\r
1298             foreach (T element in source)\r
1299             {\r
1300                 if (notAssigned)\r
1301                 {\r
1302                     maximum = element;\r
1303                     notAssigned = false;\r
1304                 }\r
1305                 else\r
1306                 {\r
1307                     int comparison;\r
1308                     if (element is IComparable<T>)\r
1309                         comparison = ((IComparable<T>)element).CompareTo(maximum);\r
1310                     else if (element is System.IComparable)\r
1311                         comparison = ((System.IComparable)element).CompareTo(maximum);\r
1312                     else\r
1313                         throw new ArgumentNullException();\r
1314 \r
1315                     if (comparison > 0)\r
1316                         maximum = element;\r
1317                 }\r
1318                 counter++;\r
1319             }\r
1320 \r
1321             if (counter == 0)\r
1322                 throw new InvalidOperationException();\r
1323             else\r
1324                 return maximum;\r
1325         }\r
1326 \r
1327 \r
1328         public static int Max<T>(this IEnumerable<T> source,\r
1329                 Func<T, int> selector)\r
1330         {\r
1331             if (source == null || selector == null)\r
1332                 throw new ArgumentNullException();\r
1333 \r
1334             int maximum = int.MinValue;\r
1335             int counter = 0;\r
1336             foreach (T item in source)\r
1337             {\r
1338                 int element = selector(item);\r
1339                 if (element > maximum)\r
1340                     maximum = element;\r
1341                 counter++;\r
1342             }\r
1343 \r
1344             if (counter == 0)\r
1345                 throw new InvalidOperationException();\r
1346             else\r
1347                 return maximum;\r
1348         }\r
1349 \r
1350 \r
1351         public static int? Max<T>(this IEnumerable<T> source,\r
1352                 Func<T, int?> selector)\r
1353         {\r
1354             if (source == null || selector == null)\r
1355                 throw new ArgumentNullException();\r
1356 \r
1357             bool onlyNull = true;\r
1358             int? maximum = int.MinValue;\r
1359             foreach (T item in source)\r
1360             {\r
1361                 int? element = selector(item);\r
1362                 if (element.HasValue)\r
1363                 {\r
1364                     onlyNull = false;\r
1365                     if (element > maximum)\r
1366                         maximum = element;\r
1367                 }\r
1368             }\r
1369             return (onlyNull ? null : maximum);\r
1370         }\r
1371 \r
1372 \r
1373         public static long Max<TSource>(this IEnumerable<TSource> source,\r
1374             Func<TSource, long> selector)\r
1375         {\r
1376             if (source == null || selector == null)\r
1377                 throw new ArgumentNullException();\r
1378 \r
1379             long maximum = long.MinValue;\r
1380             int counter = 0;\r
1381             foreach (TSource item in source)\r
1382             {\r
1383                 long element = selector(item);\r
1384                 if (element > maximum)\r
1385                     maximum = element;\r
1386                 counter++;\r
1387             }\r
1388 \r
1389             if (counter == 0)\r
1390                 throw new InvalidOperationException();\r
1391             else\r
1392                 return maximum;\r
1393         }\r
1394 \r
1395 \r
1396         public static long? Max<TSource>(this IEnumerable<TSource> source,\r
1397             Func<TSource, long?> selector)\r
1398         {\r
1399             if (source == null || selector == null)\r
1400                 throw new ArgumentNullException();\r
1401 \r
1402             bool onlyNull = true;\r
1403             long? maximum = long.MinValue;\r
1404             foreach (TSource item in source)\r
1405             {\r
1406                 long? element = selector(item);\r
1407                 if (element.HasValue)\r
1408                 {\r
1409                     onlyNull = false;\r
1410                     if (element > maximum)\r
1411                         maximum = element;\r
1412                 }\r
1413             }\r
1414             return (onlyNull ? null : maximum);\r
1415         }\r
1416 \r
1417 \r
1418         public static double Max<TSource>(this IEnumerable<TSource> source,\r
1419             Func<TSource, double> selector)\r
1420         {\r
1421             if (source == null || selector == null)\r
1422                 throw new ArgumentNullException();\r
1423 \r
1424             double maximum = double.MinValue;\r
1425             int counter = 0;\r
1426             foreach (TSource item in source)\r
1427             {\r
1428                 double element = selector(item);\r
1429                 if (element > maximum)\r
1430                     maximum = element;\r
1431                 counter++;\r
1432             }\r
1433 \r
1434             if (counter == 0)\r
1435                 throw new InvalidOperationException();\r
1436             else\r
1437                 return maximum;\r
1438         }\r
1439 \r
1440 \r
1441         public static double? Max<TSource>(this IEnumerable<TSource> source,\r
1442             Func<TSource, double?> selector)\r
1443         {\r
1444             if (source == null || selector == null)\r
1445                 throw new ArgumentNullException();\r
1446 \r
1447             bool onlyNull = true;\r
1448             double? maximum = double.MinValue;\r
1449             foreach (TSource item in source)\r
1450             {\r
1451                 double? element = selector(item);\r
1452                 if (element.HasValue)\r
1453                 {\r
1454                     onlyNull = false;\r
1455                     if (element > maximum)\r
1456                         maximum = element;\r
1457                 }\r
1458             }\r
1459             return (onlyNull ? null : maximum);\r
1460         }\r
1461 \r
1462 \r
1463         public static decimal Max<TSource>(this IEnumerable<TSource> source,\r
1464             Func<TSource, decimal> selector)\r
1465         {\r
1466             if (source == null || selector == null)\r
1467                 throw new ArgumentNullException();\r
1468 \r
1469             decimal maximum = decimal.MinValue;\r
1470             int counter = 0;\r
1471             foreach (TSource item in source)\r
1472             {\r
1473                 decimal element = selector(item);\r
1474                 if (element > maximum)\r
1475                     maximum = element;\r
1476                 counter++;\r
1477             }\r
1478 \r
1479             if (counter == 0)\r
1480                 throw new InvalidOperationException();\r
1481             else\r
1482                 return maximum;\r
1483         }\r
1484 \r
1485 \r
1486         public static decimal? Max<TSource>(this IEnumerable<TSource> source,\r
1487             Func<TSource, decimal?> selector)\r
1488         {\r
1489             if (source == null || selector == null)\r
1490                 throw new ArgumentNullException();\r
1491 \r
1492             bool onlyNull = true;\r
1493             decimal? maximum = decimal.MinValue;\r
1494             foreach (TSource item in source)\r
1495             {\r
1496                 decimal? element = selector(item);\r
1497                 if (element.HasValue)\r
1498                 {\r
1499                     onlyNull = false;\r
1500                     if (element > maximum)\r
1501                         maximum = element;\r
1502                 }\r
1503             }\r
1504             return (onlyNull ? null : maximum);\r
1505         }\r
1506 \r
1507 \r
1508         public static TResult Max<TSource, TResult>(this IEnumerable<TSource> source,\r
1509                 Func<TSource, TResult> selector)\r
1510         {\r
1511             if (source == null || selector == null)\r
1512                 throw new ArgumentNullException();\r
1513 \r
1514             bool notAssigned = true;\r
1515             TResult maximum = default(TResult);\r
1516             int counter = 0;\r
1517             foreach (TSource item in source)\r
1518             {\r
1519                 TResult element = selector(item);\r
1520                 if (notAssigned)\r
1521                 {\r
1522                     maximum = element;\r
1523                     notAssigned = false;\r
1524                 }\r
1525                 else\r
1526                 {\r
1527                     int comparison;\r
1528                     if (element is IComparable<TResult>)\r
1529                         comparison = ((IComparable<TResult>)element).CompareTo(maximum);\r
1530                     else if (element is System.IComparable)\r
1531                         comparison = ((System.IComparable)element).CompareTo(maximum);\r
1532                     else\r
1533                         throw new ArgumentNullException();\r
1534 \r
1535                     if (comparison > 0)\r
1536                         maximum = element;\r
1537                 }\r
1538                 counter++;\r
1539             }\r
1540 \r
1541             if (counter == 0)\r
1542                 throw new InvalidOperationException();\r
1543             else\r
1544                 return maximum;\r
1545         }\r
1546 \r
1547         #endregion\r
1548 \r
1549         #region Min\r
1550 \r
1551         public static int Min(this IEnumerable<int> source)\r
1552         {\r
1553             if (source == null)\r
1554                 throw new ArgumentNullException();\r
1555 \r
1556             int minimum = int.MaxValue;\r
1557             int counter = 0;\r
1558             foreach (int element in source)\r
1559             {\r
1560                 if (element < minimum)\r
1561                     minimum = element;\r
1562                 counter++;\r
1563             }\r
1564 \r
1565             if (counter == 0)\r
1566                 throw new InvalidOperationException();\r
1567             else\r
1568                 return minimum;\r
1569         }\r
1570 \r
1571 \r
1572         public static int? Min(this IEnumerable<int?> source)\r
1573         {\r
1574             if (source == null)\r
1575                 throw new ArgumentNullException();\r
1576 \r
1577             bool onlyNull = true;\r
1578             int? minimum = int.MaxValue;\r
1579             foreach (int? element in source)\r
1580             {\r
1581                 if (element.HasValue)\r
1582                 {\r
1583                     onlyNull = false;\r
1584                     if (element < minimum)\r
1585                         minimum = element;\r
1586                 }\r
1587             }\r
1588             return (onlyNull ? null : minimum);\r
1589         }\r
1590 \r
1591         public static long Min(this IEnumerable<long> source)\r
1592         {\r
1593             if (source == null)\r
1594                 throw new ArgumentNullException();\r
1595 \r
1596             long minimum = long.MaxValue;\r
1597             int counter = 0;\r
1598             foreach (long element in source)\r
1599             {\r
1600                 if (element < minimum)\r
1601                     minimum = element;\r
1602                 counter++;\r
1603             }\r
1604 \r
1605             if (counter == 0)\r
1606                 throw new InvalidOperationException();\r
1607             else\r
1608                 return minimum;\r
1609         }\r
1610 \r
1611 \r
1612         public static long? Min(this IEnumerable<long?> source)\r
1613         {\r
1614             if (source == null)\r
1615                 throw new ArgumentNullException();\r
1616 \r
1617             bool onlyNull = true;\r
1618             long? minimum = long.MaxValue;\r
1619             foreach (long? element in source)\r
1620             {\r
1621                 if (element.HasValue)\r
1622                 {\r
1623                     onlyNull = false;\r
1624                     if (element < minimum)\r
1625                         minimum = element;\r
1626                 }\r
1627             }\r
1628             return (onlyNull ? null : minimum);\r
1629         }\r
1630 \r
1631 \r
1632         public static double Min(this IEnumerable<double> source)\r
1633         {\r
1634             if (source == null)\r
1635                 throw new ArgumentNullException();\r
1636 \r
1637             double minimum = double.MaxValue;\r
1638             int counter = 0;\r
1639             foreach (double element in source)\r
1640             {\r
1641                 if (element < minimum)\r
1642                     minimum = element;\r
1643                 counter++;\r
1644             }\r
1645 \r
1646             if (counter == 0)\r
1647                 throw new InvalidOperationException();\r
1648             else\r
1649                 return minimum;\r
1650         }\r
1651 \r
1652 \r
1653         public static double? Min(this IEnumerable<double?> source)\r
1654         {\r
1655             if (source == null)\r
1656                 throw new ArgumentNullException();\r
1657 \r
1658             bool onlyNull = true;\r
1659             double? minimum = double.MaxValue;\r
1660             foreach (double? element in source)\r
1661             {\r
1662                 if (element.HasValue)\r
1663                 {\r
1664                     onlyNull = false;\r
1665                     if (element < minimum)\r
1666                         minimum = element;\r
1667                 }\r
1668             }\r
1669             return (onlyNull ? null : minimum);\r
1670         }\r
1671 \r
1672 \r
1673         public static decimal Min(this IEnumerable<decimal> source)\r
1674         {\r
1675             if (source == null)\r
1676                 throw new ArgumentNullException();\r
1677 \r
1678             decimal minimum = decimal.MaxValue;\r
1679             int counter = 0;\r
1680             foreach (decimal element in source)\r
1681             {\r
1682                 if (element < minimum)\r
1683                     minimum = element;\r
1684                 counter++;\r
1685             }\r
1686 \r
1687             if (counter == 0)\r
1688                 throw new InvalidOperationException();\r
1689             else\r
1690                 return minimum;\r
1691         }\r
1692 \r
1693 \r
1694         public static decimal? Min(this IEnumerable<decimal?> source)\r
1695         {\r
1696             if (source == null)\r
1697                 throw new ArgumentNullException();\r
1698 \r
1699             bool onlyNull = true;\r
1700             decimal? minimum = decimal.MaxValue;\r
1701             foreach (decimal? element in source)\r
1702             {\r
1703                 if (element.HasValue)\r
1704                 {\r
1705                     onlyNull = false;\r
1706                     if (element < minimum)\r
1707                         minimum = element;\r
1708                 }\r
1709             }\r
1710             return (onlyNull ? null : minimum);\r
1711         }\r
1712 \r
1713 \r
1714         public static TSource Min<TSource>(this IEnumerable<TSource> source)\r
1715         {\r
1716             if (source == null)\r
1717                 throw new ArgumentNullException();\r
1718 \r
1719             bool notAssigned = true;\r
1720             TSource minimum = default(TSource);\r
1721             int counter = 0;\r
1722             foreach (TSource element in source)\r
1723             {\r
1724                 if (notAssigned)\r
1725                 {\r
1726                     minimum = element;\r
1727                     notAssigned = false;\r
1728                 }\r
1729                 else\r
1730                 {\r
1731                     int comparison;\r
1732                     if (element is IComparable<TSource>)\r
1733                         comparison = ((IComparable<TSource>)element).CompareTo(minimum);\r
1734                     else if (element is System.IComparable)\r
1735                         comparison = ((System.IComparable)element).CompareTo(minimum);\r
1736                     else\r
1737                         throw new ArgumentNullException();\r
1738 \r
1739                     if (comparison < 0)\r
1740                         minimum = element;\r
1741                 }\r
1742                 counter++;\r
1743             }\r
1744 \r
1745             if (counter == 0)\r
1746                 throw new InvalidOperationException();\r
1747             else\r
1748                 return minimum;\r
1749         }\r
1750 \r
1751 \r
1752         public static int Min<TSource>(this IEnumerable<TSource> source,\r
1753             Func<TSource, int> selector)\r
1754         {\r
1755             if (source == null || selector == null)\r
1756                 throw new ArgumentNullException();\r
1757 \r
1758             int minimum = int.MaxValue;\r
1759             int counter = 0;\r
1760             foreach (TSource item in source)\r
1761             {\r
1762                 int element = selector(item);\r
1763                 if (element < minimum)\r
1764                     minimum = element;\r
1765                 counter++;\r
1766             }\r
1767 \r
1768             if (counter == 0)\r
1769                 throw new InvalidOperationException();\r
1770             else\r
1771                 return minimum;\r
1772         }\r
1773 \r
1774 \r
1775         public static int? Min<TSource>(this IEnumerable<TSource> source,\r
1776                 Func<TSource, int?> selector)\r
1777         {\r
1778             if (source == null || selector == null)\r
1779                 throw new ArgumentNullException();\r
1780 \r
1781             bool onlyNull = true;\r
1782             int? minimum = int.MaxValue;\r
1783             foreach (TSource item in source)\r
1784             {\r
1785                 int? element = selector(item);\r
1786                 if (element.HasValue)\r
1787                 {\r
1788                     onlyNull = false;\r
1789                     if (element < minimum)\r
1790                         minimum = element;\r
1791                 }\r
1792             }\r
1793             return (onlyNull ? null : minimum);\r
1794         }\r
1795 \r
1796 \r
1797         public static long Min<TSource>(this IEnumerable<TSource> source,\r
1798                 Func<TSource, long> selector)\r
1799         {\r
1800             if (source == null || selector == null)\r
1801                 throw new ArgumentNullException();\r
1802 \r
1803             long minimum = long.MaxValue;\r
1804             int counter = 0;\r
1805             foreach (TSource item in source)\r
1806             {\r
1807                 long element = selector(item);\r
1808                 if (element < minimum)\r
1809                     minimum = element;\r
1810                 counter++;\r
1811             }\r
1812 \r
1813             if (counter == 0)\r
1814                 throw new InvalidOperationException();\r
1815             else\r
1816                 return minimum;\r
1817         }\r
1818 \r
1819 \r
1820         public static long? Min<TSource>(this IEnumerable<TSource> source,\r
1821                 Func<TSource, long?> selector)\r
1822         {\r
1823             if (source == null || selector == null)\r
1824                 throw new ArgumentNullException();\r
1825 \r
1826             bool onlyNull = true;\r
1827             long? minimum = long.MaxValue;\r
1828             foreach (TSource item in source)\r
1829             {\r
1830                 long? element = selector(item);\r
1831                 if (element.HasValue)\r
1832                 {\r
1833                     onlyNull = false;\r
1834                     if (element < minimum)\r
1835                         minimum = element;\r
1836                 }\r
1837             }\r
1838             return (onlyNull ? null : minimum);\r
1839         }\r
1840 \r
1841 \r
1842         public static double Min<TSource>(this IEnumerable<TSource> source,\r
1843             Func<TSource, double> selector)\r
1844         {\r
1845             if (source == null || selector == null)\r
1846                 throw new ArgumentNullException();\r
1847 \r
1848             double minimum = double.MaxValue;\r
1849             int counter = 0;\r
1850             foreach (TSource item in source)\r
1851             {\r
1852                 double element = selector(item);\r
1853                 if (element < minimum)\r
1854                     minimum = element;\r
1855                 counter++;\r
1856             }\r
1857 \r
1858             if (counter == 0)\r
1859                 throw new InvalidOperationException();\r
1860             else\r
1861                 return minimum;\r
1862         }\r
1863 \r
1864 \r
1865         public static double? Min<TSource>(this IEnumerable<TSource> source,\r
1866                 Func<TSource, double?> selector)\r
1867         {\r
1868             if (source == null || selector == null)\r
1869                 throw new ArgumentNullException();\r
1870 \r
1871             bool onlyNull = true;\r
1872             double? minimum = double.MaxValue;\r
1873             foreach (TSource item in source)\r
1874             {\r
1875                 double? element = selector(item);\r
1876                 if (element.HasValue)\r
1877                 {\r
1878                     onlyNull = false;\r
1879                     if (element < minimum)\r
1880                         minimum = element;\r
1881                 }\r
1882             }\r
1883             return (onlyNull ? null : minimum);\r
1884         }\r
1885 \r
1886 \r
1887         public static decimal Min<TSource>(this IEnumerable<TSource> source,\r
1888                 Func<TSource, decimal> selector)\r
1889         {\r
1890             if (source == null || selector == null)\r
1891                 throw new ArgumentNullException();\r
1892 \r
1893             decimal minimum = decimal.MaxValue;\r
1894             int counter = 0;\r
1895             foreach (TSource item in source)\r
1896             {\r
1897                 decimal element = selector(item);\r
1898                 if (element < minimum)\r
1899                     minimum = element;\r
1900                 counter++;\r
1901             }\r
1902 \r
1903             if (counter == 0)\r
1904                 throw new InvalidOperationException();\r
1905             else\r
1906                 return minimum;\r
1907         }\r
1908 \r
1909 \r
1910         public static decimal? Min<TSource>(this IEnumerable<TSource> source,\r
1911                 Func<TSource, decimal?> selector)\r
1912         {\r
1913             if (source == null || selector == null)\r
1914                 throw new ArgumentNullException();\r
1915 \r
1916             bool onlyNull = true;\r
1917             decimal? minimum = decimal.MaxValue;\r
1918             foreach (TSource item in source)\r
1919             {\r
1920                 decimal? element = selector(item);\r
1921                 if (element.HasValue)\r
1922                 {\r
1923                     onlyNull = false;\r
1924                     if (element < minimum)\r
1925                         minimum = element;\r
1926                 }\r
1927             }\r
1928             return (onlyNull ? null : minimum);\r
1929         }\r
1930 \r
1931 \r
1932         public static TResult Min<TSource, TResult>(this IEnumerable<TSource> source,\r
1933                 Func<TSource, TResult> selector)\r
1934         {\r
1935             if (source == null || selector == null)\r
1936                 throw new ArgumentNullException();\r
1937 \r
1938             bool notAssigned = true;\r
1939             TResult minimum = default(TResult);\r
1940             int counter = 0;\r
1941             foreach (TSource item in source)\r
1942             {\r
1943                 TResult element = selector(item);\r
1944                 if (notAssigned)\r
1945                 {\r
1946                     minimum = element;\r
1947                     notAssigned = false;\r
1948                 }\r
1949                 else\r
1950                 {\r
1951                     int comparison;\r
1952                     if (element is IComparable<TResult>)\r
1953                         comparison = ((IComparable<TResult>)element).CompareTo(minimum);\r
1954                     else if (element is System.IComparable)\r
1955                         comparison = ((System.IComparable)element).CompareTo(minimum);\r
1956                     else\r
1957                         throw new ArgumentNullException();\r
1958 \r
1959                     if (comparison < 0)\r
1960                         minimum = element;\r
1961                 }\r
1962                 counter++;\r
1963             }\r
1964 \r
1965             if (counter == 0)\r
1966                 throw new InvalidOperationException();\r
1967             else\r
1968                 return minimum;\r
1969         }\r
1970 \r
1971         #endregion\r
1972 \r
1973         #region OfType\r
1974 \r
1975         public static IEnumerable<TSource> OfType<TSource>(this IEnumerable source)\r
1976         {\r
1977             if (source == null)\r
1978                 throw new ArgumentNullException();\r
1979 \r
1980             foreach (object element in source)\r
1981                 if (element is TSource)\r
1982                     yield return (TSource)element;\r
1983         }\r
1984 \r
1985         #endregion\r
1986 \r
1987         #region OrderBy\r
1988 \r
1989         public static OrderedSequence<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source,\r
1990                 Func<TSource, TKey> keySelector)\r
1991         {\r
1992             return OrderBy<TSource, TKey>(source, keySelector, null);\r
1993         }\r
1994 \r
1995 \r
1996         public static OrderedSequence<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source,\r
1997                 Func<TSource, TKey> keySelector,\r
1998                 IComparer<TKey> comparer)\r
1999         {\r
2000             if (source == null || keySelector == null)\r
2001                 throw new ArgumentNullException();\r
2002 \r
2003             return new InternalOrderedSequence<TSource, TKey>(\r
2004                     source, keySelector, (comparer ?? Comparer<TKey>.Default), false, null);\r
2005         }\r
2006 \r
2007         #endregion\r
2008 \r
2009         #region OrderByDescending\r
2010 \r
2011         public static OrderedSequence<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source,\r
2012                 Func<TSource, TKey> keySelector)\r
2013         {\r
2014             return OrderByDescending<TSource, TKey>(source, keySelector, null);\r
2015         }\r
2016 \r
2017 \r
2018         public static OrderedSequence<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source,\r
2019                 Func<TSource, TKey> keySelector, IComparer<TKey> comparer)\r
2020         {\r
2021             if (source == null || keySelector == null)\r
2022                 throw new ArgumentNullException();\r
2023 \r
2024             return new InternalOrderedSequence<TSource, TKey>(\r
2025                     source, keySelector, (comparer ?? Comparer<TKey>.Default), true, null);\r
2026         }\r
2027 \r
2028         #endregion\r
2029 \r
2030         #region Range\r
2031 \r
2032         public static IEnumerable<int> Range(int start, int count)\r
2033         {\r
2034             if (count < 0 || (start + count - 1) > int.MaxValue)\r
2035                 throw new ArgumentOutOfRangeException();\r
2036 \r
2037             for (int i = start; i < (start + count - 1); i++)\r
2038                 yield return i;\r
2039         }\r
2040 \r
2041         #endregion\r
2042 \r
2043         #region Repeat\r
2044 \r
2045         public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)\r
2046         {\r
2047             if (count < 0)\r
2048                 throw new ArgumentOutOfRangeException();\r
2049 \r
2050             for (int i = 0; i < count; i++)\r
2051                 yield return element;\r
2052         }\r
2053 \r
2054         #endregion\r
2055 \r
2056 \r
2057         #region Reverse\r
2058 \r
2059         public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source)\r
2060         {\r
2061             if (source == null)\r
2062                 throw new ArgumentNullException();\r
2063 \r
2064             List<TSource> list = new List<TSource>(source);\r
2065             list.Reverse();\r
2066             return list;\r
2067         }\r
2068 \r
2069         #endregion\r
2070 \r
2071         #region Select\r
2072 \r
2073         public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source,\r
2074                 Func<TSource, TResult> selector)\r
2075         {\r
2076             if (source == null || selector == null)\r
2077                 throw new ArgumentNullException();\r
2078 \r
2079             foreach (TSource element in source)\r
2080                 yield return selector(element);\r
2081         }\r
2082 \r
2083 \r
2084         public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source,\r
2085                 Func<TSource, int, TResult> selector)\r
2086         {\r
2087             if (source == null || selector == null)\r
2088                 throw new ArgumentNullException();\r
2089 \r
2090             int counter = 0;\r
2091             foreach (TSource element in source)\r
2092             {\r
2093                 yield return selector(element, counter);\r
2094                 counter++;\r
2095             }\r
2096         }\r
2097 \r
2098         #endregion\r
2099 \r
2100         #region SelectMany\r
2101 \r
2102         public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source,\r
2103                 Func<TSource, IEnumerable<TResult>> selector)\r
2104         {\r
2105             if (source == null || selector == null)\r
2106                 throw new ArgumentNullException();\r
2107 \r
2108             foreach (TSource element in source)\r
2109                 foreach (TResult item in selector(element))\r
2110                     yield return item;\r
2111         }\r
2112 \r
2113 \r
2114         public static IEnumerable<TResult> SelectMany<TSource, TResult>(this IEnumerable<TSource> source,\r
2115                 Func<TSource, int, IEnumerable<TResult>> selector)\r
2116         {\r
2117             if (source == null || selector == null)\r
2118                 throw new ArgumentNullException();\r
2119 \r
2120             int counter = 0;\r
2121             foreach (TSource element in source)\r
2122             {\r
2123                 foreach (TResult item in selector(element, counter))\r
2124                     yield return item;\r
2125                 counter++;\r
2126             }\r
2127         }\r
2128 \r
2129         #endregion\r
2130 \r
2131         #region Single\r
2132 \r
2133         public static TSource Single<TSource>(this IEnumerable<TSource> source)\r
2134         {\r
2135             if (source == null)\r
2136                 throw new ArgumentNullException();\r
2137 \r
2138             bool otherElement = false;\r
2139             TSource singleElement = default(TSource);\r
2140             foreach (TSource element in source)\r
2141             {\r
2142                 if (otherElement) throw new InvalidOperationException();\r
2143                 if (!otherElement) otherElement = true;\r
2144                 singleElement = element;\r
2145             }\r
2146 \r
2147             if (otherElement)\r
2148                 return singleElement;\r
2149             else\r
2150                 throw new InvalidOperationException();\r
2151         }\r
2152 \r
2153 \r
2154         public static TSource Single<TSource>(this IEnumerable<TSource> source,\r
2155                 Func<TSource, bool> predicate)\r
2156         {\r
2157             if (source == null || predicate == null)\r
2158                 throw new ArgumentNullException();\r
2159 \r
2160             bool otherElement = false;\r
2161             TSource singleElement = default(TSource);\r
2162             foreach (TSource element in source)\r
2163             {\r
2164                 if (predicate(element))\r
2165                 {\r
2166                     if (otherElement) throw new InvalidOperationException();\r
2167                     if (!otherElement) otherElement = true;\r
2168                     singleElement = element;\r
2169                 }\r
2170             }\r
2171 \r
2172             if (otherElement)\r
2173                 return singleElement;\r
2174             else\r
2175                 throw new InvalidOperationException();\r
2176         }\r
2177 \r
2178         #endregion\r
2179 \r
2180         #region SingleOrDefault\r
2181 \r
2182         public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)\r
2183         {\r
2184             if (source == null)\r
2185                 throw new ArgumentNullException();\r
2186 \r
2187             bool otherElement = false;\r
2188             TSource singleElement = default(TSource);\r
2189             foreach (TSource element in source)\r
2190             {\r
2191                 if (otherElement) throw new InvalidOperationException();\r
2192                 if (!otherElement) otherElement = true;\r
2193                 singleElement = element;\r
2194             }\r
2195 \r
2196             return singleElement;\r
2197         }\r
2198 \r
2199 \r
2200         public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source,\r
2201                 Func<TSource, bool> predicate)\r
2202         {\r
2203             if (source == null || predicate == null)\r
2204                 throw new ArgumentNullException();\r
2205 \r
2206             bool otherElement = false;\r
2207             TSource singleElement = default(TSource);\r
2208             foreach (TSource element in source)\r
2209             {\r
2210                 if (predicate(element))\r
2211                 {\r
2212                     if (otherElement) throw new InvalidOperationException();\r
2213                     if (!otherElement) otherElement = true;\r
2214                     singleElement = element;\r
2215                 }\r
2216             }\r
2217 \r
2218             return singleElement;\r
2219         }\r
2220 \r
2221         #endregion\r
2222 \r
2223         #region Skip\r
2224         public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count)\r
2225         {\r
2226             if (source == null)\r
2227                 throw new NotSupportedException();\r
2228 \r
2229             int i = 0;\r
2230             foreach (TSource e in source)\r
2231             {\r
2232                 if (++i < count)\r
2233                     continue;\r
2234                 yield return e;\r
2235             }\r
2236         }\r
2237         #endregion\r
2238 \r
2239         #region SkipWhile\r
2240 \r
2241 \r
2242         public static IEnumerable<T> SkipWhile<T>(\r
2243                 IEnumerable<T> source,\r
2244                 Func<T, bool> predicate)\r
2245         {\r
2246             if (source == null || predicate == null)\r
2247                 throw new ArgumentNullException();\r
2248 \r
2249             bool yield = false;\r
2250 \r
2251             foreach (T element in source)\r
2252             {\r
2253                 if (yield)\r
2254                     yield return element;\r
2255                 else\r
2256                     if (!predicate(element))\r
2257                     {\r
2258                         yield return element;\r
2259                         yield = true;\r
2260                     }\r
2261             }\r
2262         }\r
2263 \r
2264 \r
2265         public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source,\r
2266                 Func<TSource, int, bool> predicate)\r
2267         {\r
2268             if (source == null || predicate == null)\r
2269                 throw new ArgumentNullException();\r
2270 \r
2271             int counter = 0;\r
2272             bool yield = false;\r
2273 \r
2274             foreach (TSource element in source)\r
2275             {\r
2276                 if (yield)\r
2277                     yield return element;\r
2278                 else\r
2279                     if (!predicate(element, counter))\r
2280                     {\r
2281                         yield return element;\r
2282                         yield = true;\r
2283                     }\r
2284                 counter++;\r
2285             }\r
2286         }\r
2287 \r
2288         #endregion\r
2289 \r
2290         #region Sum\r
2291 \r
2292         public static int Sum(this IEnumerable<int> source)\r
2293         {\r
2294             if (source == null)\r
2295                 throw new ArgumentNullException("source");\r
2296 \r
2297             int sum = 0;\r
2298             foreach (int element in source)\r
2299                 sum += element;\r
2300 \r
2301             return sum;\r
2302         }\r
2303 \r
2304 \r
2305         public static int Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)\r
2306         {\r
2307             if (source == null || selector == null)\r
2308                 throw new ArgumentNullException();\r
2309 \r
2310             int sum = 0;\r
2311             foreach (TSource element in source)\r
2312                 sum += selector(element);\r
2313 \r
2314             return sum;\r
2315         }\r
2316 \r
2317 \r
2318         public static int? Sum(this IEnumerable<int?> source)\r
2319         {\r
2320             if (source == null)\r
2321                 throw new ArgumentNullException();\r
2322 \r
2323             int? sum = 0;\r
2324             foreach (int? element in source)\r
2325                 if (element.HasValue)\r
2326                     sum += element.Value;\r
2327 \r
2328             return sum;\r
2329         }\r
2330 \r
2331 \r
2332         public static int? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int?> selector)\r
2333         {\r
2334             if (source == null || selector == null)\r
2335                 throw new ArgumentNullException();\r
2336 \r
2337             int? sum = 0;\r
2338             foreach (TSource element in source)\r
2339             {\r
2340                 int? item = selector(element);\r
2341                 if (item.HasValue)\r
2342                     sum += item.Value;\r
2343             }\r
2344 \r
2345             return sum;\r
2346         }\r
2347 \r
2348 \r
2349         public static long Sum(this IEnumerable<long> source)\r
2350         {\r
2351             if (source == null)\r
2352                 throw new ArgumentNullException();\r
2353 \r
2354             long sum = 0;\r
2355             foreach (long element in source)\r
2356                 sum += element;\r
2357 \r
2358             return sum;\r
2359         }\r
2360 \r
2361 \r
2362         public static long Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long> selector)\r
2363         {\r
2364             if (source == null || selector == null)\r
2365                 throw new ArgumentNullException();\r
2366 \r
2367             long sum = 0;\r
2368             foreach (TSource element in source)\r
2369                 sum += selector(element);\r
2370 \r
2371             return sum;\r
2372         }\r
2373 \r
2374 \r
2375         public static long? Sum(this IEnumerable<long?> source)\r
2376         {\r
2377             if (source == null)\r
2378                 throw new ArgumentNullException();\r
2379 \r
2380             long? sum = 0;\r
2381             foreach (long? element in source)\r
2382                 if (element.HasValue)\r
2383                     sum += element.Value;\r
2384 \r
2385             return sum;\r
2386         }\r
2387 \r
2388 \r
2389         public static long? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, long?> selector)\r
2390         {\r
2391             if (source == null || selector == null)\r
2392                 throw new ArgumentNullException();\r
2393 \r
2394             long? sum = 0;\r
2395             foreach (TSource element in source)\r
2396             {\r
2397                 long? item = selector(element);\r
2398                 if (item.HasValue)\r
2399                     sum += item.Value;\r
2400             }\r
2401 \r
2402             return sum;\r
2403         }\r
2404 \r
2405 \r
2406         public static double Sum(this IEnumerable<double> source)\r
2407         {\r
2408             if (source == null)\r
2409                 throw new ArgumentNullException();\r
2410 \r
2411             double sum = 0;\r
2412             foreach (double element in source)\r
2413                 sum += element;\r
2414 \r
2415             return sum;\r
2416         }\r
2417 \r
2418 \r
2419         public static double Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double> selector)\r
2420         {\r
2421             if (source == null || selector == null)\r
2422                 throw new ArgumentNullException();\r
2423 \r
2424             double sum = 0;\r
2425             foreach (TSource element in source)\r
2426                 sum += selector(element);\r
2427 \r
2428             return sum;\r
2429         }\r
2430 \r
2431 \r
2432         public static double? Sum(this IEnumerable<double?> source)\r
2433         {\r
2434             if (source == null)\r
2435                 throw new ArgumentNullException();\r
2436 \r
2437             double? sum = 0;\r
2438             foreach (double? element in source)\r
2439                 if (element.HasValue)\r
2440                     sum += element.Value;\r
2441 \r
2442             return sum;\r
2443         }\r
2444 \r
2445 \r
2446         public static double? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, double?> selector)\r
2447         {\r
2448             if (source == null || selector == null)\r
2449                 throw new ArgumentNullException();\r
2450 \r
2451             double? sum = 0;\r
2452             foreach (TSource element in source)\r
2453             {\r
2454                 double? item = selector(element);\r
2455                 if (item.HasValue)\r
2456                     sum += item.Value;\r
2457             }\r
2458 \r
2459             return sum;\r
2460         }\r
2461 \r
2462 \r
2463         public static decimal Sum(this IEnumerable<decimal> source)\r
2464         {\r
2465             if (source == null)\r
2466                 throw new ArgumentNullException();\r
2467 \r
2468             decimal sum = 0;\r
2469             foreach (decimal element in source)\r
2470                 sum += element;\r
2471 \r
2472             return sum;\r
2473         }\r
2474 \r
2475 \r
2476         public static decimal Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal> selector)\r
2477         {\r
2478             if (source == null || selector == null)\r
2479                 throw new ArgumentNullException();\r
2480 \r
2481             decimal sum = 0;\r
2482             foreach (TSource element in source)\r
2483                 sum += selector(element);\r
2484 \r
2485             return sum;\r
2486         }\r
2487 \r
2488 \r
2489         public static decimal? Sum(this IEnumerable<decimal?> source)\r
2490         {\r
2491             if (source == null)\r
2492                 throw new ArgumentNullException();\r
2493 \r
2494             decimal? sum = 0;\r
2495             foreach (decimal? element in source)\r
2496                 if (element.HasValue)\r
2497                     sum += element.Value;\r
2498 \r
2499             return sum;\r
2500         }\r
2501 \r
2502 \r
2503         public static decimal? Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, decimal?> selector)\r
2504         {\r
2505             if (source == null || selector == null)\r
2506                 throw new ArgumentNullException();\r
2507 \r
2508             decimal? sum = 0;\r
2509             foreach (TSource element in source)\r
2510             {\r
2511                 decimal? item = selector(element);\r
2512                 if (item.HasValue)\r
2513                     sum += item.Value;\r
2514             }\r
2515 \r
2516             return sum;\r
2517         }\r
2518 \r
2519         #endregion\r
2520 \r        #region Take\r
2521 \r
2522         public static IEnumerable<T> Take<T>(this IEnumerable<T> source, int count)\r
2523         {\r
2524             if (source == null)\r
2525                 throw new ArgumentNullException();\r
2526 \r
2527             if (count <= 0)\r
2528                 yield break;\r
2529             else\r
2530             {\r
2531                 int counter = 0;\r
2532                 foreach (T element in source)\r
2533                 {\r
2534                     yield return element;\r
2535                     counter++;\r
2536                     if (counter == count)\r
2537                         yield break;\r
2538                 }\r
2539             }\r
2540         }\r
2541 \r
2542         #endregion\r
2543 \r
2544         #region TakeWhile\r
2545 \r
2546         public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate)\r
2547         {\r
2548             if (source == null || predicate == null)\r
2549                 throw new ArgumentNullException();\r
2550 \r
2551             foreach (T element in source)\r
2552             {\r
2553                 if (predicate(element))\r
2554                     yield return element;\r
2555                 else\r
2556                     yield break;\r
2557             }\r
2558         }\r
2559 \r
2560         public static IEnumerable<TSource> TakeWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)\r
2561         {\r
2562             if (source == null || predicate == null)\r
2563                 throw new ArgumentNullException();\r
2564 \r
2565             int counter = 0;\r
2566             foreach (TSource element in source)\r
2567             {\r
2568                 if (predicate(element, counter))\r
2569                     yield return element;\r
2570                 else\r
2571                     yield break;\r
2572                 counter++;\r
2573             }\r
2574         }\r
2575 \r
2576         #endregion\r
2577 \r
2578         #region ThenBy\r
2579 \r
2580         public static OrderedSequence<TSource> ThenBy<TSource, TKey>(this OrderedSequence<TSource> source, Func<TSource, TKey> keySelector)\r
2581         {\r
2582             return ThenBy<TSource, TKey>(source, keySelector, null);\r
2583         }\r
2584 \r
2585 \r
2586         public static OrderedSequence<TSource> ThenBy<TSource, TKey>(this OrderedSequence<TSource> source, \r
2587             Func<TSource, TKey> keySelector, IComparer<TKey> comparer)\r
2588         {\r
2589             if (source == null || keySelector == null)\r
2590                 throw new ArgumentNullException();\r
2591 \r
2592             return new InternalOrderedSequence<TSource, TKey>(\r
2593                     source, keySelector, (comparer ?? Comparer<TKey>.Default), false, source);\r
2594         }\r
2595 \r
2596         #endregion\r
2597 \r
2598         #region ThenByDescending\r
2599 \r
2600         public static OrderedSequence<TSource> ThenByDescending<TSource, TKey>(this OrderedSequence<TSource> source,\r
2601             Func<TSource, TKey> keySelector)\r
2602         {\r
2603             return ThenByDescending<TSource, TKey>(source, keySelector, null);\r
2604         }\r
2605 \r
2606 \r
2607         public static OrderedSequence<TSource> ThenByDescending<TSource, TKey>(this OrderedSequence<TSource> source,\r
2608             Func<TSource, TKey> keySelector, IComparer<TKey> comparer)\r
2609         {\r
2610             if (source == null || keySelector == null)\r
2611                 throw new ArgumentNullException();\r
2612 \r
2613             return new InternalOrderedSequence<TSource, TKey>(\r
2614                     source, keySelector, (comparer ?? Comparer<TKey>.Default), true, source);\r
2615         }\r
2616 \r
2617         #endregion
2618
2619         #region ToArray               
2620         public static T[] ToArray<T> (this IEnumerable<T> source)
2621         {
2622             if (source == null)
2623                 throw new ArgumentNullException ();
2624                         
2625             List<T> list = new List<T> (source);
2626             return list.ToArray ();
2627         }
2628                 
2629         #endregion\r
2630 \r
2631         #region ToDictionary\r
2632         public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)\r
2633         {\r
2634             return ToDictionary<TSource, TKey, TElement>(source, keySelector, elementSelector, null);\r
2635         }\r
2636 \r
2637 \r
2638         public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)\r
2639         {\r
2640             if (source == null)\r
2641                 throw new ArgumentNullException("source");\r
2642             if (keySelector == null)\r
2643                 throw new ArgumentNullException("keySelector");\r
2644             if (elementSelector == null)\r
2645                 throw new ArgumentNullException("elementSelector");\r
2646 \r
2647             Dictionary<TKey, TElement> dict = new Dictionary<TKey, TElement>(comparer);\r
2648             foreach (TSource e in source)\r
2649             {\r
2650                 dict.Add(keySelector(e), elementSelector(e));\r
2651             }\r
2652 \r
2653             return dict;\r
2654         }\r
2655         #endregion\r
2656 \r
2657         #region ToList\r
2658         public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)\r
2659         {\r
2660             if (source == null)\r
2661                 throw new ArgumentNullException("source");\r
2662 \r
2663             return new List<TSource>(source);\r
2664         }\r
2665         #endregion\r
2666 \r
2667         #region ToLookup\r
2668 \r
2669         public static Lookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)\r
2670         {\r
2671             return ToLookup<TSource, TKey>(source, keySelector, null);\r
2672         }\r
2673 \r
2674 \r
2675         public static Lookup<TKey, TSource> ToLookup<TSource, TKey>(this IEnumerable<TSource> source, \r
2676             Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)\r
2677         {\r
2678             if (source == null || keySelector == null)\r
2679                 throw new ArgumentNullException();\r
2680 \r
2681             Dictionary<TKey, List<TSource>> dictionary = new Dictionary<TKey, List<TSource>>(comparer ?? EqualityComparer<TKey>.Default);\r
2682             foreach (TSource element in source)\r
2683             {\r
2684                 TKey key = keySelector(element);\r
2685                 if (key == null)\r
2686                     throw new ArgumentNullException();\r
2687                 if (!dictionary.ContainsKey(key))\r
2688                     dictionary.Add(key, new List<TSource>());\r
2689                 dictionary[key].Add(element);\r
2690             }\r
2691             return new Lookup<TKey, TSource>(dictionary);\r
2692         }\r
2693 \r
2694 \r
2695         public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source,\r
2696             Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector)\r
2697         {\r
2698             return ToLookup<TSource, TKey, TElement>(source, keySelector, elementSelector, null);\r
2699         }\r
2700 \r
2701 \r
2702         public static Lookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(this IEnumerable<TSource> source,\r
2703             Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer)\r
2704         {\r
2705             if (source == null || keySelector == null || elementSelector == null)\r
2706                 throw new ArgumentNullException();\r
2707 \r
2708             Dictionary<TKey, List<TElement>> dictionary = new Dictionary<TKey, List<TElement>>(comparer ?? EqualityComparer<TKey>.Default);\r
2709             foreach (TSource element in source)\r
2710             {\r
2711                 TKey key = keySelector(element);\r
2712                 if (key == null)\r
2713                     throw new ArgumentNullException();\r
2714                 if (!dictionary.ContainsKey(key))\r
2715                     dictionary.Add(key, new List<TElement>());\r
2716                 dictionary[key].Add(elementSelector(element));\r
2717             }\r
2718             return new Lookup<TKey, TElement>(dictionary);\r
2719         }\r
2720 \r
2721         #endregion\r
2722 \r
2723         #region ToSequence\r
2724 \r
2725         public static IEnumerable<T> ToSequence<T>(this IEnumerable<T> source)\r
2726         {\r
2727             return (IEnumerable<T>)source;\r
2728         }\r
2729 \r
2730         #endregion\r
2731 \r
2732         #region Union\r
2733 \r
2734 \r
2735         public static IEnumerable<T> Union<T>(this IEnumerable<T> first, IEnumerable<T> second)\r
2736         {\r
2737             if (first == null || second == null)\r
2738                 throw new ArgumentNullException();\r
2739 \r
2740             List<T> items = new List<T>();\r
2741             foreach (T element in first)\r
2742             {\r
2743                 if (IndexOf(items, element) == -1)\r
2744                 {\r
2745                     items.Add(element);\r
2746                     yield return element;\r
2747                 }\r
2748             }\r
2749             foreach (T element in second)\r
2750             {\r
2751                 if (IndexOf(items, element) == -1)\r
2752                 {\r
2753                     items.Add(element);\r
2754                     yield return element;\r
2755                 }\r
2756             }\r
2757         }\r
2758 \r
2759         #endregion\r
2760 \r
2761         #region Where\r
2762 \r
2763         public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,\r
2764                 Func<TSource, bool> predicate)\r
2765         {\r
2766             if (source == null || predicate == null)\r
2767                 throw new ArgumentNullException();\r
2768 \r
2769             foreach (TSource element in source)\r
2770                 if (predicate(element))\r
2771                     yield return element;\r
2772         }\r
2773 \r
2774 \r
2775         public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,\r
2776                 Func<TSource, int, bool> predicate)\r
2777         {\r
2778             if (source == null || predicate == null)\r
2779                 throw new ArgumentNullException();\r
2780 \r
2781             int counter = 0;\r
2782             foreach (TSource element in source)\r
2783             {\r
2784                 if (predicate(element, counter))\r
2785                     yield return element;\r
2786                 counter++;\r
2787             }\r
2788         }\r
2789 \r
2790         #endregion\r
2791 \r
2792         // These methods are not included in the\r
2793         // .NET Standard Query Operators Specification,\r
2794         // but they provide additional useful commands\r
2795 \r
2796         #region Compare\r
2797 \r
2798         private static bool Equals<T>(T first, T second)\r
2799         {\r
2800             // Mostly, values in Enumerable<T> \r
2801             // sequences need to be compared using\r
2802             // Equals and GetHashCode\r
2803 \r
2804             if (first == null || second == null)\r
2805                 return (first == null && second == null);\r
2806             else\r
2807                 return ((first.Equals(second) ||\r
2808                          first.GetHashCode() == second.GetHashCode()));\r
2809         }\r
2810 \r
2811         #endregion\r
2812 \r
2813         #region IndexOf\r
2814 \r
2815         public static int IndexOf<T>(this IEnumerable<T> source, T item, IEqualityComparer<T> comparer)\r
2816         {\r
2817             if (comparer == null)\r
2818                 comparer = EqualityComparer<T>.Default;\r
2819 \r
2820             int counter = 0;\r
2821             foreach (T element in source)\r
2822             {\r
2823                 if (comparer.Equals(element, item))\r
2824                     return counter;\r
2825                 counter++;\r
2826             }\r
2827             // The item was not found\r
2828             return -1;\r
2829         }\r
2830 \r
2831         public static int IndexOf<T>(this IEnumerable<T> source, T item)\r
2832         {\r
2833             return IndexOf<T>(source, item, null);\r
2834         }\r
2835         #endregion\r
2836 \r
2837         #region ToReadOnlyCollection\r
2838         internal static ReadOnlyCollection<TSource> ToReadOnlyCollection<TSource>(IEnumerable<TSource> source)\r
2839         {\r
2840             if (source == null)\r
2841                 return new ReadOnlyCollection<TSource>(new List<TSource>());\r
2842 \r
2843             if (typeof(ReadOnlyCollection<TSource>).IsInstanceOfType(source))\r
2844                 return source as ReadOnlyCollection<TSource>;\r
2845 \r
2846             return new ReadOnlyCollection<TSource>(ToArray<TSource>(source));\r
2847         }\r
2848         #endregion\r
2849     }\r
2850 }