LinqBridge-1.3.cs 103 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100
  1. #region License, Terms and Author(s)
  2. //
  3. // LINQBridge
  4. // Copyright (c) 2007 Atif Aziz, Joseph Albahari. All rights reserved.
  5. //
  6. // Author(s):
  7. //
  8. // Atif Aziz, http://www.raboof.com
  9. //
  10. // This library is free software; you can redistribute it and/or modify it
  11. // under the terms of the New BSD License, a copy of which should have
  12. // been delivered along with this distribution.
  13. //
  14. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  17. // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  18. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  20. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. //
  26. #endregion
  27. // $Id: Enumerable.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
  28. namespace System.Linq
  29. {
  30. #region Imports
  31. using System;
  32. using System.Collections;
  33. using System.Collections.Generic;
  34. using System.Diagnostics;
  35. using LinqBridge;
  36. #endregion
  37. /// <summary>
  38. /// Provides a set of static (Shared in Visual Basic) methods for
  39. /// querying objects that implement <see cref="IEnumerable{T}" />.
  40. /// </summary>
  41. static partial class Enumerable
  42. {
  43. /// <summary>
  44. /// Returns the input typed as <see cref="IEnumerable{T}"/>.
  45. /// </summary>
  46. public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
  47. {
  48. return source;
  49. }
  50. /// <summary>
  51. /// Returns an empty <see cref="IEnumerable{T}"/> that has the
  52. /// specified type argument.
  53. /// </summary>
  54. public static IEnumerable<TResult> Empty<TResult>()
  55. {
  56. return Sequence<TResult>.Empty;
  57. }
  58. /// <summary>
  59. /// Converts the elements of an <see cref="IEnumerable"/> to the
  60. /// specified type.
  61. /// </summary>
  62. public static IEnumerable<TResult> Cast<TResult>(
  63. this IEnumerable source)
  64. {
  65. if (source == null) throw new ArgumentNullException("source");
  66. return CastYield<TResult>(source);
  67. }
  68. private static IEnumerable<TResult> CastYield<TResult>(
  69. IEnumerable source)
  70. {
  71. foreach (var item in source)
  72. yield return (TResult)item;
  73. }
  74. /// <summary>
  75. /// Filters the elements of an <see cref="IEnumerable"/> based on a specified type.
  76. /// </summary>
  77. public static IEnumerable<TResult> OfType<TResult>(
  78. this IEnumerable source)
  79. {
  80. if (source == null) throw new ArgumentNullException("source");
  81. return OfTypeYield<TResult>(source);
  82. }
  83. private static IEnumerable<TResult> OfTypeYield<TResult>(
  84. IEnumerable source)
  85. {
  86. foreach (var item in source)
  87. if (item is TResult)
  88. yield return (TResult)item;
  89. }
  90. /// <summary>
  91. /// Generates a sequence of integral numbers within a specified range.
  92. /// </summary>
  93. /// <param name="start">The value of the first integer in the sequence.</param>
  94. /// <param name="count">The number of sequential integers to generate.</param>
  95. public static IEnumerable<int> Range(int start, int count)
  96. {
  97. if (count < 0)
  98. throw new ArgumentOutOfRangeException("count", count, null);
  99. var end = (long)start + count;
  100. if (end - 1 >= int.MaxValue)
  101. throw new ArgumentOutOfRangeException("count", count, null);
  102. return RangeYield(start, end);
  103. }
  104. private static IEnumerable<int> RangeYield(int start, long end)
  105. {
  106. for (var i = start; i < end; i++)
  107. yield return i;
  108. }
  109. /// <summary>
  110. /// Generates a sequence that contains one repeated value.
  111. /// </summary>
  112. public static IEnumerable<TResult> Repeat<TResult>(TResult element, int count)
  113. {
  114. if (count < 0) throw new ArgumentOutOfRangeException("count", count, null);
  115. return RepeatYield(element, count);
  116. }
  117. private static IEnumerable<TResult> RepeatYield<TResult>(TResult element, int count)
  118. {
  119. for (var i = 0; i < count; i++)
  120. yield return element;
  121. }
  122. /// <summary>
  123. /// Filters a sequence of values based on a predicate.
  124. /// </summary>
  125. public static IEnumerable<TSource> Where<TSource>(
  126. this IEnumerable<TSource> source,
  127. FFunc<TSource, bool> predicate)
  128. {
  129. if (predicate == null) throw new ArgumentNullException("predicate");
  130. return source.Where((item, i) => predicate(item));
  131. }
  132. /// <summary>
  133. /// Filters a sequence of values based on a predicate.
  134. /// Each element's index is used in the logic of the predicate function.
  135. /// </summary>
  136. public static IEnumerable<TSource> Where<TSource>(
  137. this IEnumerable<TSource> source,
  138. FFunc<TSource, int, bool> predicate)
  139. {
  140. if (source == null) throw new ArgumentNullException("source");
  141. if (predicate == null) throw new ArgumentNullException("predicate");
  142. return WhereYield(source, predicate);
  143. }
  144. private static IEnumerable<TSource> WhereYield<TSource>(
  145. IEnumerable<TSource> source,
  146. FFunc<TSource, int, bool> predicate)
  147. {
  148. var i = 0;
  149. foreach (var item in source)
  150. if (predicate(item, i++))
  151. yield return item;
  152. }
  153. /// <summary>
  154. /// Projects each element of a sequence into a new form.
  155. /// </summary>
  156. public static IEnumerable<TResult> Select<TSource, TResult>(
  157. this IEnumerable<TSource> source,
  158. FFunc<TSource, TResult> selector)
  159. {
  160. if (selector == null) throw new ArgumentNullException("selector");
  161. return source.Select((item, i) => selector(item));
  162. }
  163. /// <summary>
  164. /// Projects each element of a sequence into a new form by
  165. /// incorporating the element's index.
  166. /// </summary>
  167. public static IEnumerable<TResult> Select<TSource, TResult>(
  168. this IEnumerable<TSource> source,
  169. FFunc<TSource, int, TResult> selector)
  170. {
  171. if (source == null) throw new ArgumentNullException("source");
  172. if (selector == null) throw new ArgumentNullException("selector");
  173. return SelectYield(source, selector);
  174. }
  175. private static IEnumerable<TResult> SelectYield<TSource, TResult>(
  176. IEnumerable<TSource> source,
  177. FFunc<TSource, int, TResult> selector)
  178. {
  179. var i = 0;
  180. foreach (var item in source)
  181. yield return selector(item, i++);
  182. }
  183. /// <summary>
  184. /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />
  185. /// and flattens the resulting sequences into one sequence.
  186. /// </summary>
  187. public static IEnumerable<TResult> SelectMany<TSource, TResult>(
  188. this IEnumerable<TSource> source,
  189. FFunc<TSource, IEnumerable<TResult>> selector)
  190. {
  191. if (selector == null) throw new ArgumentNullException("selector");
  192. return source.SelectMany((item, i) => selector(item));
  193. }
  194. /// <summary>
  195. /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
  196. /// and flattens the resulting sequences into one sequence. The
  197. /// index of each source element is used in the projected form of
  198. /// that element.
  199. /// </summary>
  200. public static IEnumerable<TResult> SelectMany<TSource, TResult>(
  201. this IEnumerable<TSource> source,
  202. FFunc<TSource, int, IEnumerable<TResult>> selector)
  203. {
  204. if (selector == null) throw new ArgumentNullException("selector");
  205. return source.SelectMany(selector, (item, subitem) => subitem);
  206. }
  207. /// <summary>
  208. /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
  209. /// flattens the resulting sequences into one sequence, and invokes
  210. /// a result selector function on each element therein.
  211. /// </summary>
  212. public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
  213. this IEnumerable<TSource> source,
  214. FFunc<TSource, IEnumerable<TCollection>> collectionSelector,
  215. FFunc<TSource, TCollection, TResult> resultSelector)
  216. {
  217. if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
  218. return source.SelectMany((item, i) => collectionSelector(item), resultSelector);
  219. }
  220. /// <summary>
  221. /// Projects each element of a sequence to an <see cref="IEnumerable{T}" />,
  222. /// flattens the resulting sequences into one sequence, and invokes
  223. /// a result selector function on each element therein. The index of
  224. /// each source element is used in the intermediate projected form
  225. /// of that element.
  226. /// </summary>
  227. public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(
  228. this IEnumerable<TSource> source,
  229. FFunc<TSource, int, IEnumerable<TCollection>> collectionSelector,
  230. FFunc<TSource, TCollection, TResult> resultSelector)
  231. {
  232. if (source == null) throw new ArgumentNullException("source");
  233. if (collectionSelector == null) throw new ArgumentNullException("collectionSelector");
  234. if (resultSelector == null) throw new ArgumentNullException("resultSelector");
  235. return SelectManyYield(source, collectionSelector, resultSelector);
  236. }
  237. private static IEnumerable<TResult> SelectManyYield<TSource, TCollection, TResult>(
  238. this IEnumerable<TSource> source,
  239. FFunc<TSource, int, IEnumerable<TCollection>> collectionSelector,
  240. FFunc<TSource, TCollection, TResult> resultSelector)
  241. {
  242. var i = 0;
  243. foreach (var item in source)
  244. foreach (var subitem in collectionSelector(item, i++))
  245. yield return resultSelector(item, subitem);
  246. }
  247. /// <summary>
  248. /// Returns elements from a sequence as long as a specified condition is true.
  249. /// </summary>
  250. public static IEnumerable<TSource> TakeWhile<TSource>(
  251. this IEnumerable<TSource> source,
  252. FFunc<TSource, bool> predicate)
  253. {
  254. if (predicate == null) throw new ArgumentNullException("predicate");
  255. return source.TakeWhile((item, i) => predicate(item));
  256. }
  257. /// <summary>
  258. /// Returns elements from a sequence as long as a specified condition is true.
  259. /// The element's index is used in the logic of the predicate function.
  260. /// </summary>
  261. public static IEnumerable<TSource> TakeWhile<TSource>(
  262. this IEnumerable<TSource> source,
  263. FFunc<TSource, int, bool> predicate)
  264. {
  265. if (source == null) throw new ArgumentNullException("source");
  266. if (predicate == null) throw new ArgumentNullException("predicate");
  267. return TakeWhileYield(source, predicate);
  268. }
  269. private static IEnumerable<TSource> TakeWhileYield<TSource>(
  270. this IEnumerable<TSource> source,
  271. FFunc<TSource, int, bool> predicate)
  272. {
  273. var i = 0;
  274. foreach (var item in source)
  275. if (predicate(item, i++))
  276. yield return item;
  277. else
  278. break;
  279. }
  280. /// <summary>
  281. /// Returns a specified number of contiguous elements from the start
  282. /// of a sequence.
  283. /// </summary>
  284. public static IEnumerable<TSource> Take<TSource>(
  285. this IEnumerable<TSource> source,
  286. int count)
  287. {
  288. return source.TakeWhile((item, i) => i < count);
  289. }
  290. private static class Futures<T>
  291. {
  292. public static readonly FFunc<T> Default = () => default(T);
  293. public static readonly FFunc<T> Undefined = () => { throw new InvalidOperationException(); };
  294. }
  295. /// <summary>
  296. /// Base implementation of First operator.
  297. /// </summary>
  298. private static TSource FirstImpl<TSource>(
  299. this IEnumerable<TSource> source,
  300. FFunc<TSource> empty)
  301. {
  302. if (source == null) throw new ArgumentNullException("source");
  303. Debug.Assert(empty != null);
  304. var list = source as IList<TSource>; // optimized case for lists
  305. if (list != null)
  306. return list.Count > 0 ? list[0] : empty();
  307. using (var e = source.GetEnumerator()) // fallback for enumeration
  308. return e.MoveNext() ? e.Current : empty();
  309. }
  310. /// <summary>
  311. /// Returns the first element of a sequence.
  312. /// </summary>
  313. public static TSource First<TSource>(
  314. this IEnumerable<TSource> source)
  315. {
  316. return source.FirstImpl(Futures<TSource>.Undefined);
  317. }
  318. /// <summary>
  319. /// Returns the first element in a sequence that satisfies a specified condition.
  320. /// </summary>
  321. public static TSource First<TSource>(
  322. this IEnumerable<TSource> source,
  323. FFunc<TSource, bool> predicate)
  324. {
  325. return First(source.Where(predicate));
  326. }
  327. /// <summary>
  328. /// Returns the first element of a sequence, or a default value if
  329. /// the sequence contains no elements.
  330. /// </summary>
  331. public static TSource FirstOrDefault<TSource>(
  332. this IEnumerable<TSource> source)
  333. {
  334. return source.FirstImpl(Futures<TSource>.Default);
  335. }
  336. /// <summary>
  337. /// Returns the first element of the sequence that satisfies a
  338. /// condition or a default value if no such element is found.
  339. /// </summary>
  340. public static TSource FirstOrDefault<TSource>(
  341. this IEnumerable<TSource> source,
  342. FFunc<TSource, bool> predicate)
  343. {
  344. return FirstOrDefault(source.Where(predicate));
  345. }
  346. /// <summary>
  347. /// Base implementation of Last operator.
  348. /// </summary>
  349. private static TSource LastImpl<TSource>(
  350. this IEnumerable<TSource> source,
  351. FFunc<TSource> empty)
  352. {
  353. if (source == null) throw new ArgumentNullException("source");
  354. var list = source as IList<TSource>; // optimized case for lists
  355. if (list != null)
  356. return list.Count > 0 ? list[list.Count - 1] : empty();
  357. using (var e = source.GetEnumerator())
  358. {
  359. if (!e.MoveNext())
  360. return empty();
  361. var last = e.Current;
  362. while (e.MoveNext())
  363. last = e.Current;
  364. return last;
  365. }
  366. }
  367. /// <summary>
  368. /// Returns the last element of a sequence.
  369. /// </summary>
  370. public static TSource Last<TSource>(
  371. this IEnumerable<TSource> source)
  372. {
  373. return source.LastImpl(Futures<TSource>.Undefined);
  374. }
  375. /// <summary>
  376. /// Returns the last element of a sequence that satisfies a
  377. /// specified condition.
  378. /// </summary>
  379. public static TSource Last<TSource>(
  380. this IEnumerable<TSource> source,
  381. FFunc<TSource, bool> predicate)
  382. {
  383. return Last(source.Where(predicate));
  384. }
  385. /// <summary>
  386. /// Returns the last element of a sequence, or a default value if
  387. /// the sequence contains no elements.
  388. /// </summary>
  389. public static TSource LastOrDefault<TSource>(
  390. this IEnumerable<TSource> source)
  391. {
  392. return source.LastImpl(Futures<TSource>.Default);
  393. }
  394. /// <summary>
  395. /// Returns the last element of a sequence that satisfies a
  396. /// condition or a default value if no such element is found.
  397. /// </summary>
  398. public static TSource LastOrDefault<TSource>(
  399. this IEnumerable<TSource> source,
  400. FFunc<TSource, bool> predicate)
  401. {
  402. return LastOrDefault(source.Where(predicate));
  403. }
  404. /// <summary>
  405. /// Base implementation of Single operator.
  406. /// </summary>
  407. private static TSource SingleImpl<TSource>(
  408. this IEnumerable<TSource> source,
  409. FFunc<TSource> empty)
  410. {
  411. if (source == null) throw new ArgumentNullException("source");
  412. using (var e = source.GetEnumerator())
  413. {
  414. if (e.MoveNext())
  415. {
  416. var single = e.Current;
  417. if (!e.MoveNext())
  418. return single;
  419. throw new InvalidOperationException();
  420. }
  421. return empty();
  422. }
  423. }
  424. /// <summary>
  425. /// Returns the only element of a sequence, and throws an exception
  426. /// if there is not exactly one element in the sequence.
  427. /// </summary>
  428. public static TSource Single<TSource>(
  429. this IEnumerable<TSource> source)
  430. {
  431. return source.SingleImpl(Futures<TSource>.Undefined);
  432. }
  433. /// <summary>
  434. /// Returns the only element of a sequence that satisfies a
  435. /// specified condition, and throws an exception if more than one
  436. /// such element exists.
  437. /// </summary>
  438. public static TSource Single<TSource>(
  439. this IEnumerable<TSource> source,
  440. FFunc<TSource, bool> predicate)
  441. {
  442. return Single(source.Where(predicate));
  443. }
  444. /// <summary>
  445. /// Returns the only element of a sequence, or a default value if
  446. /// the sequence is empty; this method throws an exception if there
  447. /// is more than one element in the sequence.
  448. /// </summary>
  449. public static TSource SingleOrDefault<TSource>(
  450. this IEnumerable<TSource> source)
  451. {
  452. return source.SingleImpl(Futures<TSource>.Default);
  453. }
  454. /// <summary>
  455. /// Returns the only element of a sequence that satisfies a
  456. /// specified condition or a default value if no such element
  457. /// exists; this method throws an exception if more than one element
  458. /// satisfies the condition.
  459. /// </summary>
  460. public static TSource SingleOrDefault<TSource>(
  461. this IEnumerable<TSource> source,
  462. FFunc<TSource, bool> predicate)
  463. {
  464. return SingleOrDefault(source.Where(predicate));
  465. }
  466. /// <summary>
  467. /// Returns the element at a specified index in a sequence.
  468. /// </summary>
  469. public static TSource ElementAt<TSource>(
  470. this IEnumerable<TSource> source,
  471. int index)
  472. {
  473. if (source == null) throw new ArgumentNullException("source");
  474. if (index < 0)
  475. throw new ArgumentOutOfRangeException("index", index, null);
  476. var list = source as IList<TSource>;
  477. if (list != null)
  478. return list[index];
  479. try
  480. {
  481. return source.SkipWhile((item, i) => i < index).First();
  482. }
  483. catch (InvalidOperationException) // if thrown by First
  484. {
  485. throw new ArgumentOutOfRangeException("index", index, null);
  486. }
  487. }
  488. /// <summary>
  489. /// Returns the element at a specified index in a sequence or a
  490. /// default value if the index is out of range.
  491. /// </summary>
  492. public static TSource ElementAtOrDefault<TSource>(
  493. this IEnumerable<TSource> source,
  494. int index)
  495. {
  496. if (source == null) throw new ArgumentNullException("source");
  497. if (index < 0)
  498. return default(TSource);
  499. var list = source as IList<TSource>;
  500. if (list != null)
  501. return index < list.Count ? list[index] : default(TSource);
  502. return source.SkipWhile((item, i) => i < index).FirstOrDefault();
  503. }
  504. /// <summary>
  505. /// Inverts the order of the elements in a sequence.
  506. /// </summary>
  507. public static IEnumerable<TSource> Reverse<TSource>(
  508. this IEnumerable<TSource> source)
  509. {
  510. if (source == null) throw new ArgumentNullException("source");
  511. return ReverseYield(source);
  512. }
  513. private static IEnumerable<TSource> ReverseYield<TSource>(IEnumerable<TSource> source)
  514. {
  515. var stack = new Stack<TSource>();
  516. foreach (var item in source)
  517. stack.Push(item);
  518. foreach (var item in stack)
  519. yield return item;
  520. }
  521. /// <summary>
  522. /// Bypasses elements in a sequence as long as a specified condition
  523. /// is true and then returns the remaining elements.
  524. /// </summary>
  525. public static IEnumerable<TSource> SkipWhile<TSource>(
  526. this IEnumerable<TSource> source,
  527. FFunc<TSource, bool> predicate)
  528. {
  529. if (predicate == null) throw new ArgumentNullException("predicate");
  530. return source.SkipWhile((item, i) => predicate(item));
  531. }
  532. /// <summary>
  533. /// Bypasses elements in a sequence as long as a specified condition
  534. /// is true and then returns the remaining elements. The element's
  535. /// index is used in the logic of the predicate function.
  536. /// </summary>
  537. public static IEnumerable<TSource> SkipWhile<TSource>(
  538. this IEnumerable<TSource> source,
  539. FFunc<TSource, int, bool> predicate)
  540. {
  541. if (source == null) throw new ArgumentNullException("source");
  542. if (predicate == null) throw new ArgumentNullException("predicate");
  543. return SkipWhileYield(source, predicate);
  544. }
  545. private static IEnumerable<TSource> SkipWhileYield<TSource>(
  546. IEnumerable<TSource> source,
  547. FFunc<TSource, int, bool> predicate)
  548. {
  549. using (var e = source.GetEnumerator())
  550. {
  551. for (var i = 0; ; i++)
  552. {
  553. if (!e.MoveNext())
  554. yield break;
  555. if (!predicate(e.Current, i))
  556. break;
  557. }
  558. do { yield return e.Current; } while (e.MoveNext());
  559. }
  560. }
  561. /// <summary>
  562. /// Bypasses a specified number of elements in a sequence and then
  563. /// returns the remaining elements.
  564. /// </summary>
  565. public static IEnumerable<TSource> Skip<TSource>(
  566. this IEnumerable<TSource> source,
  567. int count)
  568. {
  569. return source.SkipWhile((item, i) => i < count);
  570. }
  571. /// <summary>
  572. /// Returns the number of elements in a sequence.
  573. /// </summary>
  574. public static int Count<TSource>(
  575. this IEnumerable<TSource> source)
  576. {
  577. if (source == null) throw new ArgumentNullException("source");
  578. var collection = source as ICollection;
  579. return collection != null
  580. ? collection.Count
  581. : source.Aggregate(0, (count, item) => checked(count + 1));
  582. }
  583. /// <summary>
  584. /// Returns a number that represents how many elements in the
  585. /// specified sequence satisfy a condition.
  586. /// </summary>
  587. public static int Count<TSource>(
  588. this IEnumerable<TSource> source,
  589. FFunc<TSource, bool> predicate)
  590. {
  591. return Count(source.Where(predicate));
  592. }
  593. /// <summary>
  594. /// Returns an <see cref="Int64"/> that represents the total number
  595. /// of elements in a sequence.
  596. /// </summary>
  597. public static long LongCount<TSource>(
  598. this IEnumerable<TSource> source)
  599. {
  600. if (source == null) throw new ArgumentNullException("source");
  601. var array = source as Array;
  602. return array != null
  603. ? array.LongLength
  604. : source.Aggregate(0L, (count, item) => count + 1);
  605. }
  606. /// <summary>
  607. /// Returns an <see cref="Int64"/> that represents how many elements
  608. /// in a sequence satisfy a condition.
  609. /// </summary>
  610. public static long LongCount<TSource>(
  611. this IEnumerable<TSource> source,
  612. FFunc<TSource, bool> predicate)
  613. {
  614. return LongCount(source.Where(predicate));
  615. }
  616. /// <summary>
  617. /// Concatenates two sequences.
  618. /// </summary>
  619. public static IEnumerable<TSource> Concat<TSource>(
  620. this IEnumerable<TSource> first,
  621. IEnumerable<TSource> second)
  622. {
  623. if (first == null) throw new ArgumentNullException("first");
  624. if (second == null) throw new ArgumentNullException("second");
  625. return ConcatYield(first, second);
  626. }
  627. private static IEnumerable<TSource> ConcatYield<TSource>(
  628. IEnumerable<TSource> first,
  629. IEnumerable<TSource> second)
  630. {
  631. foreach (var item in first)
  632. yield return item;
  633. foreach (var item in second)
  634. yield return item;
  635. }
  636. /// <summary>
  637. /// Creates a <see cref="List{T}"/> from an <see cref="IEnumerable{T}"/>.
  638. /// </summary>
  639. public static List<TSource> ToList<TSource>(
  640. this IEnumerable<TSource> source)
  641. {
  642. if (source == null) throw new ArgumentNullException("source");
  643. return new List<TSource>(source);
  644. }
  645. /// <summary>
  646. /// Creates an array from an <see cref="IEnumerable{T}"/>.
  647. /// </summary>
  648. public static TSource[] ToArray<TSource>(
  649. this IEnumerable<TSource> source)
  650. {
  651. return source.ToList().ToArray();
  652. }
  653. /// <summary>
  654. /// Returns distinct elements from a sequence by using the default
  655. /// equality comparer to compare values.
  656. /// </summary>
  657. public static IEnumerable<TSource> Distinct<TSource>(
  658. this IEnumerable<TSource> source)
  659. {
  660. return Distinct(source, /* comparer */ null);
  661. }
  662. /// <summary>
  663. /// Returns distinct elements from a sequence by using a specified
  664. /// <see cref="IEqualityComparer{T}"/> to compare values.
  665. /// </summary>
  666. public static IEnumerable<TSource> Distinct<TSource>(
  667. this IEnumerable<TSource> source,
  668. IEqualityComparer<TSource> comparer)
  669. {
  670. if (source == null) throw new ArgumentNullException("source");
  671. return DistinctYield(source, comparer);
  672. }
  673. private static IEnumerable<TSource> DistinctYield<TSource>(
  674. IEnumerable<TSource> source,
  675. IEqualityComparer<TSource> comparer)
  676. {
  677. var set = new Dictionary<TSource, object>(comparer);
  678. var gotNull = false;
  679. foreach (var item in source)
  680. {
  681. if (item == null)
  682. {
  683. if (gotNull)
  684. continue;
  685. gotNull = true;
  686. }
  687. else
  688. {
  689. if (set.ContainsKey(item))
  690. continue;
  691. set.Add(item, null);
  692. }
  693. yield return item;
  694. }
  695. }
  696. /// <summary>
  697. /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
  698. /// <see cref="IEnumerable{T}" /> according to a specified key
  699. /// selector function.
  700. /// </summary>
  701. public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
  702. this IEnumerable<TSource> source,
  703. FFunc<TSource, TKey> keySelector)
  704. {
  705. return ToLookup(source, keySelector, e => e, /* comparer */ null);
  706. }
  707. /// <summary>
  708. /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
  709. /// <see cref="IEnumerable{T}" /> according to a specified key
  710. /// selector function and a key comparer.
  711. /// </summary>
  712. public static ILookup<TKey, TSource> ToLookup<TSource, TKey>(
  713. this IEnumerable<TSource> source,
  714. FFunc<TSource, TKey> keySelector,
  715. IEqualityComparer<TKey> comparer)
  716. {
  717. return ToLookup(source, keySelector, e => e, comparer);
  718. }
  719. /// <summary>
  720. /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
  721. /// <see cref="IEnumerable{T}" /> according to specified key
  722. /// and element selector functions.
  723. /// </summary>
  724. public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
  725. this IEnumerable<TSource> source,
  726. FFunc<TSource, TKey> keySelector,
  727. FFunc<TSource, TElement> elementSelector)
  728. {
  729. return ToLookup(source, keySelector, elementSelector, /* comparer */ null);
  730. }
  731. /// <summary>
  732. /// Creates a <see cref="Lookup{TKey,TElement}" /> from an
  733. /// <see cref="IEnumerable{T}" /> according to a specified key
  734. /// selector function, a comparer and an element selector function.
  735. /// </summary>
  736. public static ILookup<TKey, TElement> ToLookup<TSource, TKey, TElement>(
  737. this IEnumerable<TSource> source,
  738. FFunc<TSource, TKey> keySelector,
  739. FFunc<TSource, TElement> elementSelector,
  740. IEqualityComparer<TKey> comparer)
  741. {
  742. if (source == null) throw new ArgumentNullException("source");
  743. if (keySelector == null) throw new ArgumentNullException("keySelector");
  744. if (elementSelector == null) throw new ArgumentNullException("elementSelector");
  745. var lookup = new Lookup<TKey, TElement>(comparer);
  746. foreach (var item in source)
  747. {
  748. var key = keySelector(item);
  749. var grouping = (Grouping<TKey, TElement>)lookup.Find(key);
  750. if (grouping == null)
  751. {
  752. grouping = new Grouping<TKey, TElement>(key);
  753. lookup.Add(grouping);
  754. }
  755. grouping.Add(elementSelector(item));
  756. }
  757. return lookup;
  758. }
  759. /// <summary>
  760. /// Groups the elements of a sequence according to a specified key
  761. /// selector function.
  762. /// </summary>
  763. public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
  764. this IEnumerable<TSource> source,
  765. FFunc<TSource, TKey> keySelector)
  766. {
  767. return GroupBy(source, keySelector, /* comparer */ null);
  768. }
  769. /// <summary>
  770. /// Groups the elements of a sequence according to a specified key
  771. /// selector function and compares the keys by using a specified
  772. /// comparer.
  773. /// </summary>
  774. public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(
  775. this IEnumerable<TSource> source,
  776. FFunc<TSource, TKey> keySelector,
  777. IEqualityComparer<TKey> comparer)
  778. {
  779. return GroupBy(source, keySelector, e => e, comparer);
  780. }
  781. /// <summary>
  782. /// Groups the elements of a sequence according to a specified key
  783. /// selector function and projects the elements for each group by
  784. /// using a specified function.
  785. /// </summary>
  786. public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
  787. this IEnumerable<TSource> source,
  788. FFunc<TSource, TKey> keySelector,
  789. FFunc<TSource, TElement> elementSelector)
  790. {
  791. return GroupBy(source, keySelector, elementSelector, /* comparer */ null);
  792. }
  793. /// <summary>
  794. /// Groups the elements of a sequence according to a specified key
  795. /// selector function and creates a result value from each group and
  796. /// its key.
  797. /// </summary>
  798. public static IEnumerable<IGrouping<TKey, TElement>> GroupBy<TSource, TKey, TElement>(
  799. this IEnumerable<TSource> source,
  800. FFunc<TSource, TKey> keySelector,
  801. FFunc<TSource, TElement> elementSelector,
  802. IEqualityComparer<TKey> comparer)
  803. {
  804. if (source == null) throw new ArgumentNullException("source");
  805. if (keySelector == null) throw new ArgumentNullException("keySelector");
  806. if (elementSelector == null) throw new ArgumentNullException("elementSelector");
  807. return ToLookup(source, keySelector, elementSelector, comparer);
  808. }
  809. /// <summary>
  810. /// Groups the elements of a sequence according to a key selector
  811. /// function. The keys are compared by using a comparer and each
  812. /// group's elements are projected by using a specified function.
  813. /// </summary>
  814. public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
  815. this IEnumerable<TSource> source,
  816. FFunc<TSource, TKey> keySelector,
  817. FFunc<TKey, IEnumerable<TSource>, TResult> resultSelector)
  818. {
  819. return GroupBy(source, keySelector, resultSelector, /* comparer */ null);
  820. }
  821. /// <summary>
  822. /// Groups the elements of a sequence according to a specified key
  823. /// selector function and creates a result value from each group and
  824. /// its key. The elements of each group are projected by using a
  825. /// specified function.
  826. /// </summary>
  827. public static IEnumerable<TResult> GroupBy<TSource, TKey, TResult>(
  828. this IEnumerable<TSource> source,
  829. FFunc<TSource, TKey> keySelector,
  830. FFunc<TKey, IEnumerable<TSource>, TResult> resultSelector,
  831. IEqualityComparer<TKey> comparer)
  832. {
  833. if (source == null) throw new ArgumentNullException("source");
  834. if (keySelector == null) throw new ArgumentNullException("keySelector");
  835. if (resultSelector == null) throw new ArgumentNullException("resultSelector");
  836. return ToLookup(source, keySelector, comparer).Select(g => resultSelector(g.Key, g));
  837. }
  838. /// <summary>
  839. /// Groups the elements of a sequence according to a specified key
  840. /// selector function and creates a result value from each group and
  841. /// its key. The keys are compared by using a specified comparer.
  842. /// </summary>
  843. public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
  844. this IEnumerable<TSource> source,
  845. FFunc<TSource, TKey> keySelector,
  846. FFunc<TSource, TElement> elementSelector,
  847. FFunc<TKey, IEnumerable<TElement>, TResult> resultSelector)
  848. {
  849. return GroupBy(source, keySelector, elementSelector, resultSelector, /* comparer */ null);
  850. }
  851. /// <summary>
  852. /// Groups the elements of a sequence according to a specified key
  853. /// selector function and creates a result value from each group and
  854. /// its key. Key values are compared by using a specified comparer,
  855. /// and the elements of each group are projected by using a
  856. /// specified function.
  857. /// </summary>
  858. public static IEnumerable<TResult> GroupBy<TSource, TKey, TElement, TResult>(
  859. this IEnumerable<TSource> source,
  860. FFunc<TSource, TKey> keySelector,
  861. FFunc<TSource, TElement> elementSelector,
  862. FFunc<TKey, IEnumerable<TElement>, TResult> resultSelector,
  863. IEqualityComparer<TKey> comparer)
  864. {
  865. if (source == null) throw new ArgumentNullException("source");
  866. if (keySelector == null) throw new ArgumentNullException("keySelector");
  867. if (elementSelector == null) throw new ArgumentNullException("elementSelector");
  868. if (resultSelector == null) throw new ArgumentNullException("resultSelector");
  869. return ToLookup(source, keySelector, elementSelector, comparer)
  870. .Select(g => resultSelector(g.Key, g));
  871. }
  872. /// <summary>
  873. /// Applies an accumulator function over a sequence.
  874. /// </summary>
  875. public static TSource Aggregate<TSource>(
  876. this IEnumerable<TSource> source,
  877. FFunc<TSource, TSource, TSource> func)
  878. {
  879. if (source == null) throw new ArgumentNullException("source");
  880. if (func == null) throw new ArgumentNullException("func");
  881. using (var e = source.GetEnumerator())
  882. {
  883. if (!e.MoveNext())
  884. throw new InvalidOperationException();
  885. return e.Renumerable().Skip(1).Aggregate(e.Current, func);
  886. }
  887. }
  888. /// <summary>
  889. /// Applies an accumulator function over a sequence. The specified
  890. /// seed value is used as the initial accumulator value.
  891. /// </summary>
  892. public static TAccumulate Aggregate<TSource, TAccumulate>(
  893. this IEnumerable<TSource> source,
  894. TAccumulate seed,
  895. FFunc<TAccumulate, TSource, TAccumulate> func)
  896. {
  897. return Aggregate(source, seed, func, r => r);
  898. }
  899. /// <summary>
  900. /// Applies an accumulator function over a sequence. The specified
  901. /// seed value is used as the initial accumulator value, and the
  902. /// specified function is used to select the result value.
  903. /// </summary>
  904. public static TResult Aggregate<TSource, TAccumulate, TResult>(
  905. this IEnumerable<TSource> source,
  906. TAccumulate seed,
  907. FFunc<TAccumulate, TSource, TAccumulate> func,
  908. FFunc<TAccumulate, TResult> resultSelector)
  909. {
  910. if (source == null) throw new ArgumentNullException("source");
  911. if (func == null) throw new ArgumentNullException("func");
  912. if (resultSelector == null) throw new ArgumentNullException("resultSelector");
  913. var result = seed;
  914. foreach (var item in source)
  915. result = func(result, item);
  916. return resultSelector(result);
  917. }
  918. /// <summary>
  919. /// Produces the set union of two sequences by using the default
  920. /// equality comparer.
  921. /// </summary>
  922. public static IEnumerable<TSource> Union<TSource>(
  923. this IEnumerable<TSource> first,
  924. IEnumerable<TSource> second)
  925. {
  926. return Union(first, second, /* comparer */ null);
  927. }
  928. /// <summary>
  929. /// Produces the set union of two sequences by using a specified
  930. /// <see cref="IEqualityComparer{T}" />.
  931. /// </summary>
  932. public static IEnumerable<TSource> Union<TSource>(
  933. this IEnumerable<TSource> first,
  934. IEnumerable<TSource> second,
  935. IEqualityComparer<TSource> comparer)
  936. {
  937. return first.Concat(second).Distinct(comparer);
  938. }
  939. /// <summary>
  940. /// Returns the elements of the specified sequence or the type
  941. /// parameter's default value in a singleton collection if the
  942. /// sequence is empty.
  943. /// </summary>
  944. public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
  945. this IEnumerable<TSource> source)
  946. {
  947. return source.DefaultIfEmpty(default(TSource));
  948. }
  949. /// <summary>
  950. /// Returns the elements of the specified sequence or the specified
  951. /// value in a singleton collection if the sequence is empty.
  952. /// </summary>
  953. public static IEnumerable<TSource> DefaultIfEmpty<TSource>(
  954. this IEnumerable<TSource> source,
  955. TSource defaultValue)
  956. {
  957. if (source == null) throw new ArgumentNullException("source");
  958. return DefaultIfEmptyYield(source, defaultValue);
  959. }
  960. private static IEnumerable<TSource> DefaultIfEmptyYield<TSource>(
  961. IEnumerable<TSource> source,
  962. TSource defaultValue)
  963. {
  964. using (var e = source.GetEnumerator())
  965. {
  966. if (!e.MoveNext())
  967. yield return defaultValue;
  968. else
  969. do { yield return e.Current; } while (e.MoveNext());
  970. }
  971. }
  972. /// <summary>
  973. /// Determines whether all elements of a sequence satisfy a condition.
  974. /// </summary>
  975. public static bool All<TSource>(
  976. this IEnumerable<TSource> source,
  977. FFunc<TSource, bool> predicate)
  978. {
  979. if (source == null) throw new ArgumentNullException("source");
  980. if (predicate == null) throw new ArgumentNullException("predicate");
  981. foreach (var item in source)
  982. if (!predicate(item))
  983. return false;
  984. return true;
  985. }
  986. /// <summary>
  987. /// Determines whether a sequence contains any elements.
  988. /// </summary>
  989. public static bool Any<TSource>(
  990. this IEnumerable<TSource> source)
  991. {
  992. if (source == null) throw new ArgumentNullException("source");
  993. using (var e = source.GetEnumerator())
  994. return e.MoveNext();
  995. }
  996. /// <summary>
  997. /// Determines whether any element of a sequence satisfies a
  998. /// condition.
  999. /// </summary>
  1000. public static bool Any<TSource>(
  1001. this IEnumerable<TSource> source,
  1002. FFunc<TSource, bool> predicate)
  1003. {
  1004. return source.Where(predicate).Any();
  1005. }
  1006. /// <summary>
  1007. /// Determines whether a sequence contains a specified element by
  1008. /// using the default equality comparer.
  1009. /// </summary>
  1010. public static bool Contains<TSource>(
  1011. this IEnumerable<TSource> source,
  1012. TSource value)
  1013. {
  1014. return source.Contains(value, /* comparer */ null);
  1015. }
  1016. /// <summary>
  1017. /// Determines whether a sequence contains a specified element by
  1018. /// using a specified <see cref="IEqualityComparer{T}" />.
  1019. /// </summary>
  1020. public static bool Contains<TSource>(
  1021. this IEnumerable<TSource> source,
  1022. TSource value,
  1023. IEqualityComparer<TSource> comparer)
  1024. {
  1025. if (source == null) throw new ArgumentNullException("source");
  1026. if (comparer == null)
  1027. {
  1028. var collection = source as ICollection<TSource>;
  1029. if (collection != null)
  1030. return collection.Contains(value);
  1031. }
  1032. comparer = comparer ?? EqualityComparer<TSource>.Default;
  1033. return source.Any(item => comparer.Equals(item, value));
  1034. }
  1035. /// <summary>
  1036. /// Determines whether two sequences are equal by comparing the
  1037. /// elements by using the default equality comparer for their type.
  1038. /// </summary>
  1039. public static bool SequenceEqual<TSource>(
  1040. this IEnumerable<TSource> first,
  1041. IEnumerable<TSource> second)
  1042. {
  1043. return first.SequenceEqual(second, /* comparer */ null);
  1044. }
  1045. /// <summary>
  1046. /// Determines whether two sequences are equal by comparing their
  1047. /// elements by using a specified <see cref="IEqualityComparer{T}" />.
  1048. /// </summary>
  1049. public static bool SequenceEqual<TSource>(
  1050. this IEnumerable<TSource> first,
  1051. IEnumerable<TSource> second,
  1052. IEqualityComparer<TSource> comparer)
  1053. {
  1054. if (first == null) throw new ArgumentNullException("frist");
  1055. if (second == null) throw new ArgumentNullException("second");
  1056. comparer = comparer ?? EqualityComparer<TSource>.Default;
  1057. using (IEnumerator<TSource> lhs = first.GetEnumerator(),
  1058. rhs = second.GetEnumerator())
  1059. {
  1060. do
  1061. {
  1062. if (!lhs.MoveNext())
  1063. return !rhs.MoveNext();
  1064. if (!rhs.MoveNext())
  1065. return false;
  1066. }
  1067. while (comparer.Equals(lhs.Current, rhs.Current));
  1068. }
  1069. return false;
  1070. }
  1071. /// <summary>
  1072. /// Base implementation for Min/Max operator.
  1073. /// </summary>
  1074. private static TSource MinMaxImpl<TSource>(
  1075. this IEnumerable<TSource> source,
  1076. FFunc<TSource, TSource, bool> lesser)
  1077. {
  1078. if (source == null) throw new ArgumentNullException("source");
  1079. Debug.Assert(lesser != null);
  1080. if (typeof(TSource).IsClass) // ReSharper disable CompareNonConstrainedGenericWithNull
  1081. source = source.Where(e => e != null).DefaultIfEmpty(); // ReSharper restore CompareNonConstrainedGenericWithNull
  1082. return source.Aggregate((a, item) => lesser(a, item) ? a : item);
  1083. }
  1084. /// <summary>
  1085. /// Base implementation for Min/Max operator for nullable types.
  1086. /// </summary>
  1087. private static TSource? MinMaxImpl<TSource>(
  1088. this IEnumerable<TSource?> source,
  1089. TSource? seed, FFunc<TSource?, TSource?, bool> lesser) where TSource : struct
  1090. {
  1091. if (source == null) throw new ArgumentNullException("source");
  1092. Debug.Assert(lesser != null);
  1093. return source.Aggregate(seed, (a, item) => lesser(a, item) ? a : item);
  1094. // == MinMaxImpl(Repeat<TSource?>(null, 1).Concat(source), lesser);
  1095. }
  1096. /// <summary>
  1097. /// Returns the minimum value in a generic sequence.
  1098. /// </summary>
  1099. public static TSource Min<TSource>(
  1100. this IEnumerable<TSource> source)
  1101. {
  1102. var comparer = Comparer<TSource>.Default;
  1103. return source.MinMaxImpl((x, y) => comparer.Compare(x, y) < 0);
  1104. }
  1105. /// <summary>
  1106. /// Invokes a transform function on each element of a generic
  1107. /// sequence and returns the minimum resulting value.
  1108. /// </summary>
  1109. public static TResult Min<TSource, TResult>(
  1110. this IEnumerable<TSource> source,
  1111. FFunc<TSource, TResult> selector)
  1112. {
  1113. return source.Select(selector).Min();
  1114. }
  1115. /// <summary>
  1116. /// Returns the maximum value in a generic sequence.
  1117. /// </summary>
  1118. public static TSource Max<TSource>(
  1119. this IEnumerable<TSource> source)
  1120. {
  1121. var comparer = Comparer<TSource>.Default;
  1122. return source.MinMaxImpl((x, y) => comparer.Compare(x, y) > 0);
  1123. }
  1124. /// <summary>
  1125. /// Invokes a transform function on each element of a generic
  1126. /// sequence and returns the maximum resulting value.
  1127. /// </summary>
  1128. public static TResult Max<TSource, TResult>(
  1129. this IEnumerable<TSource> source,
  1130. FFunc<TSource, TResult> selector)
  1131. {
  1132. return source.Select(selector).Max();
  1133. }
  1134. /// <summary>
  1135. /// Makes an enumerator seen as enumerable once more.
  1136. /// </summary>
  1137. /// <remarks>
  1138. /// The supplied enumerator must have been started. The first element
  1139. /// returned is the element the enumerator was on when passed in.
  1140. /// DO NOT use this method if the caller must be a generator. It is
  1141. /// mostly safe among aggregate operations.
  1142. /// </remarks>
  1143. private static IEnumerable<T> Renumerable<T>(this IEnumerator<T> e)
  1144. {
  1145. Debug.Assert(e != null);
  1146. do { yield return e.Current; } while (e.MoveNext());
  1147. }
  1148. /// <summary>
  1149. /// Sorts the elements of a sequence in ascending order according to a key.
  1150. /// </summary>
  1151. public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
  1152. this IEnumerable<TSource> source,
  1153. FFunc<TSource, TKey> keySelector)
  1154. {
  1155. return source.OrderBy(keySelector, /* comparer */ null);
  1156. }
  1157. /// <summary>
  1158. /// Sorts the elements of a sequence in ascending order by using a
  1159. /// specified comparer.
  1160. /// </summary>
  1161. public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
  1162. this IEnumerable<TSource> source,
  1163. FFunc<TSource, TKey> keySelector,
  1164. IComparer<TKey> comparer)
  1165. {
  1166. if (source == null) throw new ArgumentNullException("source");
  1167. if (keySelector == null) throw new ArgumentNullException("keySelector");
  1168. return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ false);
  1169. }
  1170. /// <summary>
  1171. /// Sorts the elements of a sequence in descending order according to a key.
  1172. /// </summary>
  1173. public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
  1174. this IEnumerable<TSource> source,
  1175. FFunc<TSource, TKey> keySelector)
  1176. {
  1177. return source.OrderByDescending(keySelector, /* comparer */ null);
  1178. }
  1179. /// <summary>
  1180. /// Sorts the elements of a sequence in descending order by using a
  1181. /// specified comparer.
  1182. /// </summary>
  1183. public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(
  1184. this IEnumerable<TSource> source,
  1185. FFunc<TSource, TKey> keySelector,
  1186. IComparer<TKey> comparer)
  1187. {
  1188. if (source == null) throw new ArgumentNullException("source");
  1189. if (source == null) throw new ArgumentNullException("keySelector");
  1190. return new OrderedEnumerable<TSource, TKey>(source, keySelector, comparer, /* descending */ true);
  1191. }
  1192. /// <summary>
  1193. /// Performs a subsequent ordering of the elements in a sequence in
  1194. /// ascending order according to a key.
  1195. /// </summary>
  1196. public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
  1197. this IOrderedEnumerable<TSource> source,
  1198. FFunc<TSource, TKey> keySelector)
  1199. {
  1200. return source.ThenBy(keySelector, /* comparer */ null);
  1201. }
  1202. /// <summary>
  1203. /// Performs a subsequent ordering of the elements in a sequence in
  1204. /// ascending order by using a specified comparer.
  1205. /// </summary>
  1206. public static IOrderedEnumerable<TSource> ThenBy<TSource, TKey>(
  1207. this IOrderedEnumerable<TSource> source,
  1208. FFunc<TSource, TKey> keySelector,
  1209. IComparer<TKey> comparer)
  1210. {
  1211. if (source == null) throw new ArgumentNullException("source");
  1212. return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ false);
  1213. }
  1214. /// <summary>
  1215. /// Performs a subsequent ordering of the elements in a sequence in
  1216. /// descending order, according to a key.
  1217. /// </summary>
  1218. public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
  1219. this IOrderedEnumerable<TSource> source,
  1220. FFunc<TSource, TKey> keySelector)
  1221. {
  1222. return source.ThenByDescending(keySelector, /* comparer */ null);
  1223. }
  1224. /// <summary>
  1225. /// Performs a subsequent ordering of the elements in a sequence in
  1226. /// descending order by using a specified comparer.
  1227. /// </summary>
  1228. public static IOrderedEnumerable<TSource> ThenByDescending<TSource, TKey>(
  1229. this IOrderedEnumerable<TSource> source,
  1230. FFunc<TSource, TKey> keySelector,
  1231. IComparer<TKey> comparer)
  1232. {
  1233. if (source == null) throw new ArgumentNullException("source");
  1234. return source.CreateOrderedEnumerable(keySelector, comparer, /* descending */ true);
  1235. }
  1236. /// <summary>
  1237. /// Base implementation for Intersect and Except operators.
  1238. /// </summary>
  1239. private static IEnumerable<TSource> IntersectExceptImpl<TSource>(
  1240. this IEnumerable<TSource> first,
  1241. IEnumerable<TSource> second,
  1242. IEqualityComparer<TSource> comparer,
  1243. bool flag)
  1244. {
  1245. if (first == null) throw new ArgumentNullException("first");
  1246. if (second == null) throw new ArgumentNullException("second");
  1247. var keys = new List<Key<TSource>>();
  1248. var flags = new Dictionary<Key<TSource>, bool>(new KeyComparer<TSource>(comparer));
  1249. foreach (var item in from item in first
  1250. select new Key<TSource>(item) into item
  1251. where !flags.ContainsKey(item)
  1252. select item)
  1253. {
  1254. flags.Add(item, !flag);
  1255. keys.Add(item);
  1256. }
  1257. foreach (var item in from item in second
  1258. select new Key<TSource>(item) into item
  1259. where flags.ContainsKey(item)
  1260. select item)
  1261. {
  1262. flags[item] = flag;
  1263. }
  1264. //
  1265. // As per docs, "the marked elements are yielded in the order in
  1266. // which they were collected.
  1267. //
  1268. return from item in keys where flags[item] select item.Value;
  1269. }
  1270. /// <summary>
  1271. /// Produces the set intersection of two sequences by using the
  1272. /// default equality comparer to compare values.
  1273. /// </summary>
  1274. public static IEnumerable<TSource> Intersect<TSource>(
  1275. this IEnumerable<TSource> first,
  1276. IEnumerable<TSource> second)
  1277. {
  1278. return first.Intersect(second, /* comparer */ null);
  1279. }
  1280. /// <summary>
  1281. /// Produces the set intersection of two sequences by using the
  1282. /// specified <see cref="IEqualityComparer{T}" /> to compare values.
  1283. /// </summary>
  1284. public static IEnumerable<TSource> Intersect<TSource>(
  1285. this IEnumerable<TSource> first,
  1286. IEnumerable<TSource> second,
  1287. IEqualityComparer<TSource> comparer)
  1288. {
  1289. return IntersectExceptImpl(first, second, comparer, /* flag */ true);
  1290. }
  1291. /// <summary>
  1292. /// Produces the set difference of two sequences by using the
  1293. /// default equality comparer to compare values.
  1294. /// </summary>
  1295. public static IEnumerable<TSource> Except<TSource>(
  1296. this IEnumerable<TSource> first,
  1297. IEnumerable<TSource> second)
  1298. {
  1299. return first.Except(second, /* comparer */ null);
  1300. }
  1301. /// <summary>
  1302. /// Produces the set difference of two sequences by using the
  1303. /// specified <see cref="IEqualityComparer{T}" /> to compare values.
  1304. /// </summary>
  1305. public static IEnumerable<TSource> Except<TSource>(
  1306. this IEnumerable<TSource> first,
  1307. IEnumerable<TSource> second,
  1308. IEqualityComparer<TSource> comparer)
  1309. {
  1310. return IntersectExceptImpl(first, second, comparer, /* flag */ false);
  1311. }
  1312. /// <summary>
  1313. /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
  1314. /// <see cref="IEnumerable{T}" /> according to a specified key
  1315. /// selector function.
  1316. /// </summary>
  1317. public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
  1318. this IEnumerable<TSource> source,
  1319. FFunc<TSource, TKey> keySelector)
  1320. {
  1321. return source.ToDictionary(keySelector, /* comparer */ null);
  1322. }
  1323. /// <summary>
  1324. /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
  1325. /// <see cref="IEnumerable{T}" /> according to a specified key
  1326. /// selector function and key comparer.
  1327. /// </summary>
  1328. public static Dictionary<TKey, TSource> ToDictionary<TSource, TKey>(
  1329. this IEnumerable<TSource> source,
  1330. FFunc<TSource, TKey> keySelector,
  1331. IEqualityComparer<TKey> comparer)
  1332. {
  1333. return source.ToDictionary(keySelector, e => e, comparer);
  1334. }
  1335. /// <summary>
  1336. /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
  1337. /// <see cref="IEnumerable{T}" /> according to specified key
  1338. /// selector and element selector functions.
  1339. /// </summary>
  1340. public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
  1341. this IEnumerable<TSource> source,
  1342. FFunc<TSource, TKey> keySelector,
  1343. FFunc<TSource, TElement> elementSelector)
  1344. {
  1345. return source.ToDictionary(keySelector, elementSelector, /* comparer */ null);
  1346. }
  1347. /// <summary>
  1348. /// Creates a <see cref="Dictionary{TKey,TValue}" /> from an
  1349. /// <see cref="IEnumerable{T}" /> according to a specified key
  1350. /// selector function, a comparer, and an element selector function.
  1351. /// </summary>
  1352. public static Dictionary<TKey, TElement> ToDictionary<TSource, TKey, TElement>(
  1353. this IEnumerable<TSource> source,
  1354. FFunc<TSource, TKey> keySelector,
  1355. FFunc<TSource, TElement> elementSelector,
  1356. IEqualityComparer<TKey> comparer)
  1357. {
  1358. if (source == null) throw new ArgumentNullException("source");
  1359. if (keySelector == null) throw new ArgumentNullException("keySelector");
  1360. if (elementSelector == null) throw new ArgumentNullException("elementSelector");
  1361. var dict = new Dictionary<TKey, TElement>(comparer);
  1362. foreach (var item in source)
  1363. {
  1364. //
  1365. // ToDictionary is meant to throw ArgumentNullException if
  1366. // keySelector produces a key that is null and
  1367. // Argument exception if keySelector produces duplicate keys
  1368. // for two elements. Incidentally, the doucmentation for
  1369. // IDictionary<TKey, TValue>.Add says that the Add method
  1370. // throws the same exceptions under the same circumstances
  1371. // so we don't need to do any additional checking or work
  1372. // here and let the Add implementation do all the heavy
  1373. // lifting.
  1374. //
  1375. dict.Add(keySelector(item), elementSelector(item));
  1376. }
  1377. return dict;
  1378. }
  1379. /// <summary>
  1380. /// Correlates the elements of two sequences based on matching keys.
  1381. /// The default equality comparer is used to compare keys.
  1382. /// </summary>
  1383. public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
  1384. this IEnumerable<TOuter> outer,
  1385. IEnumerable<TInner> inner,
  1386. FFunc<TOuter, TKey> outerKeySelector,
  1387. FFunc<TInner, TKey> innerKeySelector,
  1388. FFunc<TOuter, TInner, TResult> resultSelector)
  1389. {
  1390. return outer.Join(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
  1391. }
  1392. /// <summary>
  1393. /// Correlates the elements of two sequences based on matching keys.
  1394. /// The default equality comparer is used to compare keys. A
  1395. /// specified <see cref="IEqualityComparer{T}" /> is used to compare keys.
  1396. /// </summary>
  1397. public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
  1398. this IEnumerable<TOuter> outer,
  1399. IEnumerable<TInner> inner,
  1400. FFunc<TOuter, TKey> outerKeySelector,
  1401. FFunc<TInner, TKey> innerKeySelector,
  1402. FFunc<TOuter, TInner, TResult> resultSelector,
  1403. IEqualityComparer<TKey> comparer)
  1404. {
  1405. if (outer == null) throw new ArgumentNullException("outer");
  1406. if (inner == null) throw new ArgumentNullException("inner");
  1407. if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
  1408. if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
  1409. if (resultSelector == null) throw new ArgumentNullException("resultSelector");
  1410. var lookup = inner.ToLookup(innerKeySelector, comparer);
  1411. return
  1412. from o in outer
  1413. from i in lookup[outerKeySelector(o)]
  1414. select resultSelector(o, i);
  1415. }
  1416. /// <summary>
  1417. /// Correlates the elements of two sequences based on equality of
  1418. /// keys and groups the results. The default equality comparer is
  1419. /// used to compare keys.
  1420. /// </summary>
  1421. public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
  1422. this IEnumerable<TOuter> outer,
  1423. IEnumerable<TInner> inner,
  1424. FFunc<TOuter, TKey> outerKeySelector,
  1425. FFunc<TInner, TKey> innerKeySelector,
  1426. FFunc<TOuter, IEnumerable<TInner>, TResult> resultSelector)
  1427. {
  1428. return outer.GroupJoin(inner, outerKeySelector, innerKeySelector, resultSelector, /* comparer */ null);
  1429. }
  1430. /// <summary>
  1431. /// Correlates the elements of two sequences based on equality of
  1432. /// keys and groups the results. The default equality comparer is
  1433. /// used to compare keys. A specified <see cref="IEqualityComparer{T}" />
  1434. /// is used to compare keys.
  1435. /// </summary>
  1436. public static IEnumerable<TResult> GroupJoin<TOuter, TInner, TKey, TResult>(
  1437. this IEnumerable<TOuter> outer,
  1438. IEnumerable<TInner> inner,
  1439. FFunc<TOuter, TKey> outerKeySelector,
  1440. FFunc<TInner, TKey> innerKeySelector,
  1441. FFunc<TOuter, IEnumerable<TInner>, TResult> resultSelector,
  1442. IEqualityComparer<TKey> comparer)
  1443. {
  1444. if (outer == null) throw new ArgumentNullException("outer");
  1445. if (inner == null) throw new ArgumentNullException("inner");
  1446. if (outerKeySelector == null) throw new ArgumentNullException("outerKeySelector");
  1447. if (innerKeySelector == null) throw new ArgumentNullException("innerKeySelector");
  1448. if (resultSelector == null) throw new ArgumentNullException("resultSelector");
  1449. var lookup = inner.ToLookup(innerKeySelector, comparer);
  1450. return outer.Select(o => resultSelector(o, lookup[outerKeySelector(o)]));
  1451. }
  1452. private static class Sequence<T>
  1453. {
  1454. public static readonly IEnumerable<T> Empty = new T[0];
  1455. }
  1456. private sealed class Grouping<K, V> : List<V>, IGrouping<K, V>
  1457. {
  1458. internal Grouping(K key)
  1459. {
  1460. Key = key;
  1461. }
  1462. public K Key { get; private set; }
  1463. }
  1464. }
  1465. }
  1466. // $Id: Enumerable.g.tt 71137f497bf2 2012/04/16 20:01:27 azizatif $
  1467. namespace System.Linq
  1468. {
  1469. #region Imports
  1470. using System;
  1471. using System.Collections.Generic;
  1472. #endregion
  1473. // This partial implementation was template-generated:
  1474. // Mon, 16 Apr 2012 20:05:53 GMT
  1475. partial class Enumerable
  1476. {
  1477. /// <summary>
  1478. /// Computes the sum of a sequence of nullable <see cref="System.Int32" /> values.
  1479. /// </summary>
  1480. public static int Sum(
  1481. this IEnumerable<int> source)
  1482. {
  1483. if (source == null) throw new ArgumentNullException("source");
  1484. int sum = 0;
  1485. foreach (var num in source)
  1486. sum = checked(sum + num);
  1487. return sum;
  1488. }
  1489. /// <summary>
  1490. /// Computes the sum of a sequence of nullable <see cref="System.Int32" />
  1491. /// values that are obtained by invoking a transform function on
  1492. /// each element of the input sequence.
  1493. /// </summary>
  1494. public static int Sum<TSource>(
  1495. this IEnumerable<TSource> source,
  1496. FFunc<TSource, int> selector)
  1497. {
  1498. return source.Select(selector).Sum();
  1499. }
  1500. /// <summary>
  1501. /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values.
  1502. /// </summary>
  1503. public static double Average(
  1504. this IEnumerable<int> source)
  1505. {
  1506. if (source == null) throw new ArgumentNullException("source");
  1507. long sum = 0;
  1508. long count = 0;
  1509. foreach (var num in source)
  1510. checked
  1511. {
  1512. sum += (int)num;
  1513. count++;
  1514. }
  1515. if (count == 0)
  1516. throw new InvalidOperationException();
  1517. return (double)sum / count;
  1518. }
  1519. /// <summary>
  1520. /// Computes the average of a sequence of nullable <see cref="System.Int32" /> values
  1521. /// that are obtained by invoking a transform function on each
  1522. /// element of the input sequence.
  1523. /// </summary>
  1524. public static double Average<TSource>(
  1525. this IEnumerable<TSource> source,
  1526. FFunc<TSource, int> selector)
  1527. {
  1528. return source.Select(selector).Average();
  1529. }
  1530. /// <summary>
  1531. /// Computes the sum of a sequence of <see cref="System.Int32" /> values.
  1532. /// </summary>
  1533. public static int? Sum(
  1534. this IEnumerable<int?> source)
  1535. {
  1536. if (source == null) throw new ArgumentNullException("source");
  1537. int sum = 0;
  1538. foreach (var num in source)
  1539. sum = checked(sum + (num ?? 0));
  1540. return sum;
  1541. }
  1542. /// <summary>
  1543. /// Computes the sum of a sequence of <see cref="System.Int32" />
  1544. /// values that are obtained by invoking a transform function on
  1545. /// each element of the input sequence.
  1546. /// </summary>
  1547. public static int? Sum<TSource>(
  1548. this IEnumerable<TSource> source,
  1549. FFunc<TSource, int?> selector)
  1550. {
  1551. return source.Select(selector).Sum();
  1552. }
  1553. /// <summary>
  1554. /// Computes the average of a sequence of <see cref="System.Int32" /> values.
  1555. /// </summary>
  1556. public static double? Average(
  1557. this IEnumerable<int?> source)
  1558. {
  1559. if (source == null) throw new ArgumentNullException("source");
  1560. long sum = 0;
  1561. long count = 0;
  1562. foreach (var num in source.Where(n => n != null))
  1563. checked
  1564. {
  1565. sum += (int)num;
  1566. count++;
  1567. }
  1568. if (count == 0)
  1569. return null;
  1570. return (double?)sum / count;
  1571. }
  1572. /// <summary>
  1573. /// Computes the average of a sequence of <see cref="System.Int32" /> values
  1574. /// that are obtained by invoking a transform function on each
  1575. /// element of the input sequence.
  1576. /// </summary>
  1577. public static double? Average<TSource>(
  1578. this IEnumerable<TSource> source,
  1579. FFunc<TSource, int?> selector)
  1580. {
  1581. return source.Select(selector).Average();
  1582. }
  1583. /// <summary>
  1584. /// Returns the minimum value in a sequence of nullable
  1585. /// <see cref="System.Int32" /> values.
  1586. /// </summary>
  1587. public static int? Min(
  1588. this IEnumerable<int?> source)
  1589. {
  1590. if (source == null) throw new ArgumentNullException("source");
  1591. return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
  1592. }
  1593. /// <summary>
  1594. /// Invokes a transform function on each element of a sequence and
  1595. /// returns the minimum nullable <see cref="System.Int32" /> value.
  1596. /// </summary>
  1597. public static int? Min<TSource>(
  1598. this IEnumerable<TSource> source,
  1599. FFunc<TSource, int?> selector)
  1600. {
  1601. return source.Select(selector).Min();
  1602. }
  1603. /// <summary>
  1604. /// Returns the maximum value in a sequence of nullable
  1605. /// <see cref="System.Int32" /> values.
  1606. /// </summary>
  1607. public static int? Max(
  1608. this IEnumerable<int?> source)
  1609. {
  1610. if (source == null) throw new ArgumentNullException("source");
  1611. return MinMaxImpl(source.Where(x => x != null),
  1612. null, (max, x) => x == null || (max != null && x.Value < max.Value));
  1613. }
  1614. /// <summary>
  1615. /// Invokes a transform function on each element of a sequence and
  1616. /// returns the maximum nullable <see cref="System.Int32" /> value.
  1617. /// </summary>
  1618. public static int? Max<TSource>(
  1619. this IEnumerable<TSource> source,
  1620. FFunc<TSource, int?> selector)
  1621. {
  1622. return source.Select(selector).Max();
  1623. }
  1624. /// <summary>
  1625. /// Computes the sum of a sequence of nullable <see cref="System.Int64" /> values.
  1626. /// </summary>
  1627. public static long Sum(
  1628. this IEnumerable<long> source)
  1629. {
  1630. if (source == null) throw new ArgumentNullException("source");
  1631. long sum = 0;
  1632. foreach (var num in source)
  1633. sum = checked(sum + num);
  1634. return sum;
  1635. }
  1636. /// <summary>
  1637. /// Computes the sum of a sequence of nullable <see cref="System.Int64" />
  1638. /// values that are obtained by invoking a transform function on
  1639. /// each element of the input sequence.
  1640. /// </summary>
  1641. public static long Sum<TSource>(
  1642. this IEnumerable<TSource> source,
  1643. FFunc<TSource, long> selector)
  1644. {
  1645. return source.Select(selector).Sum();
  1646. }
  1647. /// <summary>
  1648. /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values.
  1649. /// </summary>
  1650. public static double Average(
  1651. this IEnumerable<long> source)
  1652. {
  1653. if (source == null) throw new ArgumentNullException("source");
  1654. long sum = 0;
  1655. long count = 0;
  1656. foreach (var num in source)
  1657. checked
  1658. {
  1659. sum += (long)num;
  1660. count++;
  1661. }
  1662. if (count == 0)
  1663. throw new InvalidOperationException();
  1664. return (double)sum / count;
  1665. }
  1666. /// <summary>
  1667. /// Computes the average of a sequence of nullable <see cref="System.Int64" /> values
  1668. /// that are obtained by invoking a transform function on each
  1669. /// element of the input sequence.
  1670. /// </summary>
  1671. public static double Average<TSource>(
  1672. this IEnumerable<TSource> source,
  1673. FFunc<TSource, long> selector)
  1674. {
  1675. return source.Select(selector).Average();
  1676. }
  1677. /// <summary>
  1678. /// Computes the sum of a sequence of <see cref="System.Int64" /> values.
  1679. /// </summary>
  1680. public static long? Sum(
  1681. this IEnumerable<long?> source)
  1682. {
  1683. if (source == null) throw new ArgumentNullException("source");
  1684. long sum = 0;
  1685. foreach (var num in source)
  1686. sum = checked(sum + (num ?? 0));
  1687. return sum;
  1688. }
  1689. /// <summary>
  1690. /// Computes the sum of a sequence of <see cref="System.Int64" />
  1691. /// values that are obtained by invoking a transform function on
  1692. /// each element of the input sequence.
  1693. /// </summary>
  1694. public static long? Sum<TSource>(
  1695. this IEnumerable<TSource> source,
  1696. FFunc<TSource, long?> selector)
  1697. {
  1698. return source.Select(selector).Sum();
  1699. }
  1700. /// <summary>
  1701. /// Computes the average of a sequence of <see cref="System.Int64" /> values.
  1702. /// </summary>
  1703. public static double? Average(
  1704. this IEnumerable<long?> source)
  1705. {
  1706. if (source == null) throw new ArgumentNullException("source");
  1707. long sum = 0;
  1708. long count = 0;
  1709. foreach (var num in source.Where(n => n != null))
  1710. checked
  1711. {
  1712. sum += (long)num;
  1713. count++;
  1714. }
  1715. if (count == 0)
  1716. return null;
  1717. return (double?)sum / count;
  1718. }
  1719. /// <summary>
  1720. /// Computes the average of a sequence of <see cref="System.Int64" /> values
  1721. /// that are obtained by invoking a transform function on each
  1722. /// element of the input sequence.
  1723. /// </summary>
  1724. public static double? Average<TSource>(
  1725. this IEnumerable<TSource> source,
  1726. FFunc<TSource, long?> selector)
  1727. {
  1728. return source.Select(selector).Average();
  1729. }
  1730. /// <summary>
  1731. /// Returns the minimum value in a sequence of nullable
  1732. /// <see cref="System.Int64" /> values.
  1733. /// </summary>
  1734. public static long? Min(
  1735. this IEnumerable<long?> source)
  1736. {
  1737. if (source == null) throw new ArgumentNullException("source");
  1738. return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
  1739. }
  1740. /// <summary>
  1741. /// Invokes a transform function on each element of a sequence and
  1742. /// returns the minimum nullable <see cref="System.Int64" /> value.
  1743. /// </summary>
  1744. public static long? Min<TSource>(
  1745. this IEnumerable<TSource> source,
  1746. FFunc<TSource, long?> selector)
  1747. {
  1748. return source.Select(selector).Min();
  1749. }
  1750. /// <summary>
  1751. /// Returns the maximum value in a sequence of nullable
  1752. /// <see cref="System.Int64" /> values.
  1753. /// </summary>
  1754. public static long? Max(
  1755. this IEnumerable<long?> source)
  1756. {
  1757. if (source == null) throw new ArgumentNullException("source");
  1758. return MinMaxImpl(source.Where(x => x != null),
  1759. null, (max, x) => x == null || (max != null && x.Value < max.Value));
  1760. }
  1761. /// <summary>
  1762. /// Invokes a transform function on each element of a sequence and
  1763. /// returns the maximum nullable <see cref="System.Int64" /> value.
  1764. /// </summary>
  1765. public static long? Max<TSource>(
  1766. this IEnumerable<TSource> source,
  1767. FFunc<TSource, long?> selector)
  1768. {
  1769. return source.Select(selector).Max();
  1770. }
  1771. /// <summary>
  1772. /// Computes the sum of a sequence of nullable <see cref="System.Single" /> values.
  1773. /// </summary>
  1774. public static float Sum(
  1775. this IEnumerable<float> source)
  1776. {
  1777. if (source == null) throw new ArgumentNullException("source");
  1778. float sum = 0;
  1779. foreach (var num in source)
  1780. sum = checked(sum + num);
  1781. return sum;
  1782. }
  1783. /// <summary>
  1784. /// Computes the sum of a sequence of nullable <see cref="System.Single" />
  1785. /// values that are obtained by invoking a transform function on
  1786. /// each element of the input sequence.
  1787. /// </summary>
  1788. public static float Sum<TSource>(
  1789. this IEnumerable<TSource> source,
  1790. FFunc<TSource, float> selector)
  1791. {
  1792. return source.Select(selector).Sum();
  1793. }
  1794. /// <summary>
  1795. /// Computes the average of a sequence of nullable <see cref="System.Single" /> values.
  1796. /// </summary>
  1797. public static float Average(
  1798. this IEnumerable<float> source)
  1799. {
  1800. if (source == null) throw new ArgumentNullException("source");
  1801. float sum = 0;
  1802. long count = 0;
  1803. foreach (var num in source)
  1804. checked
  1805. {
  1806. sum += (float)num;
  1807. count++;
  1808. }
  1809. if (count == 0)
  1810. throw new InvalidOperationException();
  1811. return (float)sum / count;
  1812. }
  1813. /// <summary>
  1814. /// Computes the average of a sequence of nullable <see cref="System.Single" /> values
  1815. /// that are obtained by invoking a transform function on each
  1816. /// element of the input sequence.
  1817. /// </summary>
  1818. public static float Average<TSource>(
  1819. this IEnumerable<TSource> source,
  1820. FFunc<TSource, float> selector)
  1821. {
  1822. return source.Select(selector).Average();
  1823. }
  1824. /// <summary>
  1825. /// Computes the sum of a sequence of <see cref="System.Single" /> values.
  1826. /// </summary>
  1827. public static float? Sum(
  1828. this IEnumerable<float?> source)
  1829. {
  1830. if (source == null) throw new ArgumentNullException("source");
  1831. float sum = 0;
  1832. foreach (var num in source)
  1833. sum = checked(sum + (num ?? 0));
  1834. return sum;
  1835. }
  1836. /// <summary>
  1837. /// Computes the sum of a sequence of <see cref="System.Single" />
  1838. /// values that are obtained by invoking a transform function on
  1839. /// each element of the input sequence.
  1840. /// </summary>
  1841. public static float? Sum<TSource>(
  1842. this IEnumerable<TSource> source,
  1843. FFunc<TSource, float?> selector)
  1844. {
  1845. return source.Select(selector).Sum();
  1846. }
  1847. /// <summary>
  1848. /// Computes the average of a sequence of <see cref="System.Single" /> values.
  1849. /// </summary>
  1850. public static float? Average(
  1851. this IEnumerable<float?> source)
  1852. {
  1853. if (source == null) throw new ArgumentNullException("source");
  1854. float sum = 0;
  1855. long count = 0;
  1856. foreach (var num in source.Where(n => n != null))
  1857. checked
  1858. {
  1859. sum += (float)num;
  1860. count++;
  1861. }
  1862. if (count == 0)
  1863. return null;
  1864. return (float?)sum / count;
  1865. }
  1866. /// <summary>
  1867. /// Computes the average of a sequence of <see cref="System.Single" /> values
  1868. /// that are obtained by invoking a transform function on each
  1869. /// element of the input sequence.
  1870. /// </summary>
  1871. public static float? Average<TSource>(
  1872. this IEnumerable<TSource> source,
  1873. FFunc<TSource, float?> selector)
  1874. {
  1875. return source.Select(selector).Average();
  1876. }
  1877. /// <summary>
  1878. /// Returns the minimum value in a sequence of nullable
  1879. /// <see cref="System.Single" /> values.
  1880. /// </summary>
  1881. public static float? Min(
  1882. this IEnumerable<float?> source)
  1883. {
  1884. if (source == null) throw new ArgumentNullException("source");
  1885. return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
  1886. }
  1887. /// <summary>
  1888. /// Invokes a transform function on each element of a sequence and
  1889. /// returns the minimum nullable <see cref="System.Single" /> value.
  1890. /// </summary>
  1891. public static float? Min<TSource>(
  1892. this IEnumerable<TSource> source,
  1893. FFunc<TSource, float?> selector)
  1894. {
  1895. return source.Select(selector).Min();
  1896. }
  1897. /// <summary>
  1898. /// Returns the maximum value in a sequence of nullable
  1899. /// <see cref="System.Single" /> values.
  1900. /// </summary>
  1901. public static float? Max(
  1902. this IEnumerable<float?> source)
  1903. {
  1904. if (source == null) throw new ArgumentNullException("source");
  1905. return MinMaxImpl(source.Where(x => x != null),
  1906. null, (max, x) => x == null || (max != null && x.Value < max.Value));
  1907. }
  1908. /// <summary>
  1909. /// Invokes a transform function on each element of a sequence and
  1910. /// returns the maximum nullable <see cref="System.Single" /> value.
  1911. /// </summary>
  1912. public static float? Max<TSource>(
  1913. this IEnumerable<TSource> source,
  1914. FFunc<TSource, float?> selector)
  1915. {
  1916. return source.Select(selector).Max();
  1917. }
  1918. /// <summary>
  1919. /// Computes the sum of a sequence of nullable <see cref="System.Double" /> values.
  1920. /// </summary>
  1921. public static double Sum(
  1922. this IEnumerable<double> source)
  1923. {
  1924. if (source == null) throw new ArgumentNullException("source");
  1925. double sum = 0;
  1926. foreach (var num in source)
  1927. sum = checked(sum + num);
  1928. return sum;
  1929. }
  1930. /// <summary>
  1931. /// Computes the sum of a sequence of nullable <see cref="System.Double" />
  1932. /// values that are obtained by invoking a transform function on
  1933. /// each element of the input sequence.
  1934. /// </summary>
  1935. public static double Sum<TSource>(
  1936. this IEnumerable<TSource> source,
  1937. FFunc<TSource, double> selector)
  1938. {
  1939. return source.Select(selector).Sum();
  1940. }
  1941. /// <summary>
  1942. /// Computes the average of a sequence of nullable <see cref="System.Double" /> values.
  1943. /// </summary>
  1944. public static double Average(
  1945. this IEnumerable<double> source)
  1946. {
  1947. if (source == null) throw new ArgumentNullException("source");
  1948. double sum = 0;
  1949. long count = 0;
  1950. foreach (var num in source)
  1951. checked
  1952. {
  1953. sum += (double)num;
  1954. count++;
  1955. }
  1956. if (count == 0)
  1957. throw new InvalidOperationException();
  1958. return (double)sum / count;
  1959. }
  1960. /// <summary>
  1961. /// Computes the average of a sequence of nullable <see cref="System.Double" /> values
  1962. /// that are obtained by invoking a transform function on each
  1963. /// element of the input sequence.
  1964. /// </summary>
  1965. public static double Average<TSource>(
  1966. this IEnumerable<TSource> source,
  1967. FFunc<TSource, double> selector)
  1968. {
  1969. return source.Select(selector).Average();
  1970. }
  1971. /// <summary>
  1972. /// Computes the sum of a sequence of <see cref="System.Double" /> values.
  1973. /// </summary>
  1974. public static double? Sum(
  1975. this IEnumerable<double?> source)
  1976. {
  1977. if (source == null) throw new ArgumentNullException("source");
  1978. double sum = 0;
  1979. foreach (var num in source)
  1980. sum = checked(sum + (num ?? 0));
  1981. return sum;
  1982. }
  1983. /// <summary>
  1984. /// Computes the sum of a sequence of <see cref="System.Double" />
  1985. /// values that are obtained by invoking a transform function on
  1986. /// each element of the input sequence.
  1987. /// </summary>
  1988. public static double? Sum<TSource>(
  1989. this IEnumerable<TSource> source,
  1990. FFunc<TSource, double?> selector)
  1991. {
  1992. return source.Select(selector).Sum();
  1993. }
  1994. /// <summary>
  1995. /// Computes the average of a sequence of <see cref="System.Double" /> values.
  1996. /// </summary>
  1997. public static double? Average(
  1998. this IEnumerable<double?> source)
  1999. {
  2000. if (source == null) throw new ArgumentNullException("source");
  2001. double sum = 0;
  2002. long count = 0;
  2003. foreach (var num in source.Where(n => n != null))
  2004. checked
  2005. {
  2006. sum += (double)num;
  2007. count++;
  2008. }
  2009. if (count == 0)
  2010. return null;
  2011. return (double?)sum / count;
  2012. }
  2013. /// <summary>
  2014. /// Computes the average of a sequence of <see cref="System.Double" /> values
  2015. /// that are obtained by invoking a transform function on each
  2016. /// element of the input sequence.
  2017. /// </summary>
  2018. public static double? Average<TSource>(
  2019. this IEnumerable<TSource> source,
  2020. FFunc<TSource, double?> selector)
  2021. {
  2022. return source.Select(selector).Average();
  2023. }
  2024. /// <summary>
  2025. /// Returns the minimum value in a sequence of nullable
  2026. /// <see cref="System.Double" /> values.
  2027. /// </summary>
  2028. public static double? Min(
  2029. this IEnumerable<double?> source)
  2030. {
  2031. if (source == null) throw new ArgumentNullException("source");
  2032. return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
  2033. }
  2034. /// <summary>
  2035. /// Invokes a transform function on each element of a sequence and
  2036. /// returns the minimum nullable <see cref="System.Double" /> value.
  2037. /// </summary>
  2038. public static double? Min<TSource>(
  2039. this IEnumerable<TSource> source,
  2040. FFunc<TSource, double?> selector)
  2041. {
  2042. return source.Select(selector).Min();
  2043. }
  2044. /// <summary>
  2045. /// Returns the maximum value in a sequence of nullable
  2046. /// <see cref="System.Double" /> values.
  2047. /// </summary>
  2048. public static double? Max(
  2049. this IEnumerable<double?> source)
  2050. {
  2051. if (source == null) throw new ArgumentNullException("source");
  2052. return MinMaxImpl(source.Where(x => x != null),
  2053. null, (max, x) => x == null || (max != null && x.Value < max.Value));
  2054. }
  2055. /// <summary>
  2056. /// Invokes a transform function on each element of a sequence and
  2057. /// returns the maximum nullable <see cref="System.Double" /> value.
  2058. /// </summary>
  2059. public static double? Max<TSource>(
  2060. this IEnumerable<TSource> source,
  2061. FFunc<TSource, double?> selector)
  2062. {
  2063. return source.Select(selector).Max();
  2064. }
  2065. /// <summary>
  2066. /// Computes the sum of a sequence of nullable <see cref="System.Decimal" /> values.
  2067. /// </summary>
  2068. public static decimal Sum(
  2069. this IEnumerable<decimal> source)
  2070. {
  2071. if (source == null) throw new ArgumentNullException("source");
  2072. decimal sum = 0;
  2073. foreach (var num in source)
  2074. sum = checked(sum + num);
  2075. return sum;
  2076. }
  2077. /// <summary>
  2078. /// Computes the sum of a sequence of nullable <see cref="System.Decimal" />
  2079. /// values that are obtained by invoking a transform function on
  2080. /// each element of the input sequence.
  2081. /// </summary>
  2082. public static decimal Sum<TSource>(
  2083. this IEnumerable<TSource> source,
  2084. FFunc<TSource, decimal> selector)
  2085. {
  2086. return source.Select(selector).Sum();
  2087. }
  2088. /// <summary>
  2089. /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values.
  2090. /// </summary>
  2091. public static decimal Average(
  2092. this IEnumerable<decimal> source)
  2093. {
  2094. if (source == null) throw new ArgumentNullException("source");
  2095. decimal sum = 0;
  2096. long count = 0;
  2097. foreach (var num in source)
  2098. checked
  2099. {
  2100. sum += (decimal)num;
  2101. count++;
  2102. }
  2103. if (count == 0)
  2104. throw new InvalidOperationException();
  2105. return (decimal)sum / count;
  2106. }
  2107. /// <summary>
  2108. /// Computes the average of a sequence of nullable <see cref="System.Decimal" /> values
  2109. /// that are obtained by invoking a transform function on each
  2110. /// element of the input sequence.
  2111. /// </summary>
  2112. public static decimal Average<TSource>(
  2113. this IEnumerable<TSource> source,
  2114. FFunc<TSource, decimal> selector)
  2115. {
  2116. return source.Select(selector).Average();
  2117. }
  2118. /// <summary>
  2119. /// Computes the sum of a sequence of <see cref="System.Decimal" /> values.
  2120. /// </summary>
  2121. public static decimal? Sum(
  2122. this IEnumerable<decimal?> source)
  2123. {
  2124. if (source == null) throw new ArgumentNullException("source");
  2125. decimal sum = 0;
  2126. foreach (var num in source)
  2127. sum = checked(sum + (num ?? 0));
  2128. return sum;
  2129. }
  2130. /// <summary>
  2131. /// Computes the sum of a sequence of <see cref="System.Decimal" />
  2132. /// values that are obtained by invoking a transform function on
  2133. /// each element of the input sequence.
  2134. /// </summary>
  2135. public static decimal? Sum<TSource>(
  2136. this IEnumerable<TSource> source,
  2137. FFunc<TSource, decimal?> selector)
  2138. {
  2139. return source.Select(selector).Sum();
  2140. }
  2141. /// <summary>
  2142. /// Computes the average of a sequence of <see cref="System.Decimal" /> values.
  2143. /// </summary>
  2144. public static decimal? Average(
  2145. this IEnumerable<decimal?> source)
  2146. {
  2147. if (source == null) throw new ArgumentNullException("source");
  2148. decimal sum = 0;
  2149. long count = 0;
  2150. foreach (var num in source.Where(n => n != null))
  2151. checked
  2152. {
  2153. sum += (decimal)num;
  2154. count++;
  2155. }
  2156. if (count == 0)
  2157. return null;
  2158. return (decimal?)sum / count;
  2159. }
  2160. /// <summary>
  2161. /// Computes the average of a sequence of <see cref="System.Decimal" /> values
  2162. /// that are obtained by invoking a transform function on each
  2163. /// element of the input sequence.
  2164. /// </summary>
  2165. public static decimal? Average<TSource>(
  2166. this IEnumerable<TSource> source,
  2167. FFunc<TSource, decimal?> selector)
  2168. {
  2169. return source.Select(selector).Average();
  2170. }
  2171. /// <summary>
  2172. /// Returns the minimum value in a sequence of nullable
  2173. /// <see cref="System.Decimal" /> values.
  2174. /// </summary>
  2175. public static decimal? Min(
  2176. this IEnumerable<decimal?> source)
  2177. {
  2178. if (source == null) throw new ArgumentNullException("source");
  2179. return MinMaxImpl(source.Where(x => x != null), null, (min, x) => min < x);
  2180. }
  2181. /// <summary>
  2182. /// Invokes a transform function on each element of a sequence and
  2183. /// returns the minimum nullable <see cref="System.Decimal" /> value.
  2184. /// </summary>
  2185. public static decimal? Min<TSource>(
  2186. this IEnumerable<TSource> source,
  2187. FFunc<TSource, decimal?> selector)
  2188. {
  2189. return source.Select(selector).Min();
  2190. }
  2191. /// <summary>
  2192. /// Returns the maximum value in a sequence of nullable
  2193. /// <see cref="System.Decimal" /> values.
  2194. /// </summary>
  2195. public static decimal? Max(
  2196. this IEnumerable<decimal?> source)
  2197. {
  2198. if (source == null) throw new ArgumentNullException("source");
  2199. return MinMaxImpl(source.Where(x => x != null),
  2200. null, (max, x) => x == null || (max != null && x.Value < max.Value));
  2201. }
  2202. /// <summary>
  2203. /// Invokes a transform function on each element of a sequence and
  2204. /// returns the maximum nullable <see cref="System.Decimal" /> value.
  2205. /// </summary>
  2206. public static decimal? Max<TSource>(
  2207. this IEnumerable<TSource> source,
  2208. FFunc<TSource, decimal?> selector)
  2209. {
  2210. return source.Select(selector).Max();
  2211. }
  2212. }
  2213. }
  2214. // $Id: ExtensionAttribute.cs 898b3d493ed6 2012/04/17 20:09:57 azizatif $
  2215. namespace System.Runtime.CompilerServices
  2216. {
  2217. /// <remarks>
  2218. /// This attribute allows us to define extension methods without
  2219. /// requiring .NET Framework 3.5. For more information, see the section,
  2220. /// <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx#S7">Extension Methods in .NET Framework 2.0 Apps</a>,
  2221. /// of <a href="http://msdn.microsoft.com/en-us/magazine/cc163317.aspx">Basic Instincts: Extension Methods</a>
  2222. /// column in <a href="http://msdn.microsoft.com/msdnmag/">MSDN Magazine</a>,
  2223. /// issue <a href="http://msdn.microsoft.com/en-us/magazine/cc135410.aspx">Nov 2007</a>.
  2224. /// </remarks>
  2225. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
  2226. public sealed partial class ExtensionAttribute : Attribute { }
  2227. }
  2228. // $Id: Func.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
  2229. namespace System
  2230. {
  2231. #if LINQBRIDGE_LIB
  2232. public delegate TResult FFunc<out TResult>();
  2233. public delegate TResult FFunc<in T, out TResult>(T a);
  2234. public delegate TResult FFunc<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
  2235. public delegate TResult FFunc<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
  2236. public delegate TResult FFunc<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
  2237. #else
  2238. public delegate TResult FFunc<TResult>();
  2239. public delegate TResult FFunc<T, TResult>(T a);
  2240. public delegate TResult FFunc<T1, T2, TResult>(T1 arg1, T2 arg2);
  2241. public delegate TResult FFunc<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
  2242. public delegate TResult FFunc<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
  2243. #endif
  2244. }
  2245. // $Id: IGrouping.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
  2246. namespace System.Linq
  2247. {
  2248. #region Imports
  2249. using System.Collections.Generic;
  2250. #endregion
  2251. /// <summary>
  2252. /// Represents a collection of objects that have a common key.
  2253. /// </summary>
  2254. partial interface IGrouping<out TKey, TElement> : IEnumerable<TElement>
  2255. {
  2256. /// <summary>
  2257. /// Gets the key of the <see cref="IGrouping{TKey,TElement}" />.
  2258. /// </summary>
  2259. TKey Key { get; }
  2260. }
  2261. }
  2262. // $Id: ILookup.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
  2263. namespace System.Linq
  2264. {
  2265. using System.Collections.Generic;
  2266. /// <summary>
  2267. /// Defines an indexer, size property, and Boolean search method for
  2268. /// data structures that map keys to <see cref="IEnumerable{T}"/>
  2269. /// sequences of values.
  2270. /// </summary>
  2271. partial interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>
  2272. {
  2273. bool Contains(TKey key);
  2274. int Count { get; }
  2275. IEnumerable<TElement> this[TKey key] { get; }
  2276. }
  2277. }
  2278. // $Id: Internal.cs 1567e00f1a20 2012/04/17 16:09:51 azizatif $
  2279. namespace LinqBridge
  2280. {
  2281. #region Imports
  2282. using System;
  2283. using System.Collections.Generic;
  2284. #endregion
  2285. /// <remarks>
  2286. /// This type is not intended to be used directly from user code.
  2287. /// It may be removed or changed in a future version without notice.
  2288. /// </remarks>
  2289. sealed class DelegatingComparer<T> : IComparer<T>
  2290. {
  2291. private readonly FFunc<T, T, int> _comparer;
  2292. public DelegatingComparer(FFunc<T, T, int> comparer)
  2293. {
  2294. if (comparer == null) throw new ArgumentNullException("comparer");
  2295. _comparer = comparer;
  2296. }
  2297. public int Compare(T x, T y) { return _comparer(x, y); }
  2298. }
  2299. /// <remarks>
  2300. /// This type is not intended to be used directly from user code.
  2301. /// It may be removed or changed in a future version without notice.
  2302. /// </remarks>
  2303. struct Key<T>
  2304. {
  2305. public Key(T value) : this() { Value = value; }
  2306. public T Value { get; private set; }
  2307. }
  2308. /// <remarks>
  2309. /// This type is not intended to be used directly from user code.
  2310. /// It may be removed or changed in a future version without notice.
  2311. /// </remarks>
  2312. sealed class KeyComparer<T> : IEqualityComparer<Key<T>>
  2313. {
  2314. private readonly IEqualityComparer<T> _innerComparer;
  2315. public KeyComparer(IEqualityComparer<T> innerComparer)
  2316. {
  2317. _innerComparer = innerComparer ?? EqualityComparer<T>.Default;
  2318. }
  2319. public bool Equals(Key<T> x, Key<T> y)
  2320. {
  2321. return _innerComparer.Equals(x.Value, y.Value);
  2322. }
  2323. public int GetHashCode(Key<T> obj)
  2324. {
  2325. return obj.Value == null ? 0 : _innerComparer.GetHashCode(obj.Value);
  2326. }
  2327. }
  2328. }
  2329. // $Id: IOrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
  2330. namespace System.Linq
  2331. {
  2332. using System.Collections.Generic;
  2333. /// <summary>
  2334. /// Represents a sorted sequence.
  2335. /// </summary>
  2336. partial interface IOrderedEnumerable<TElement> : IEnumerable<TElement>
  2337. {
  2338. /// <summary>
  2339. /// Performs a subsequent ordering on the elements of an
  2340. /// <see cref="IOrderedEnumerable{T}"/> according to a key.
  2341. /// </summary>
  2342. IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(
  2343. FFunc<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);
  2344. }
  2345. }
  2346. // $Id: Lookup.cs c08984d432b1 2012/04/17 16:05:19 azizatif $
  2347. namespace System.Linq
  2348. {
  2349. #region Imports
  2350. using System;
  2351. using System.Collections;
  2352. using System.Collections.Generic;
  2353. using IEnumerable = System.Collections.IEnumerable;
  2354. using LinqBridge;
  2355. #endregion
  2356. /// <summary>
  2357. /// Represents a collection of keys each mapped to one or more values.
  2358. /// </summary>
  2359. internal sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement>
  2360. {
  2361. private readonly Dictionary<Key<TKey>, IGrouping<TKey, TElement>> _map;
  2362. private readonly List<Key<TKey>> _orderedKeys; // remember order of insertion
  2363. internal Lookup(IEqualityComparer<TKey> comparer)
  2364. {
  2365. _map = new Dictionary<Key<TKey>, IGrouping<TKey, TElement>>(new KeyComparer<TKey>(comparer));
  2366. _orderedKeys = new List<Key<TKey>>();
  2367. }
  2368. internal void Add(IGrouping<TKey, TElement> item)
  2369. {
  2370. var key = new Key<TKey>(item.Key);
  2371. _map.Add(key, item);
  2372. _orderedKeys.Add(key);
  2373. }
  2374. internal IEnumerable<TElement> Find(TKey key)
  2375. {
  2376. IGrouping<TKey, TElement> grouping;
  2377. return _map.TryGetValue(new Key<TKey>(key), out grouping) ? grouping : null;
  2378. }
  2379. /// <summary>
  2380. /// Gets the number of key/value collection pairs in the <see cref="Lookup{TKey,TElement}" />.
  2381. /// </summary>
  2382. public int Count
  2383. {
  2384. get { return _map.Count; }
  2385. }
  2386. /// <summary>
  2387. /// Gets the collection of values indexed by the specified key.
  2388. /// </summary>
  2389. public IEnumerable<TElement> this[TKey key]
  2390. {
  2391. get
  2392. {
  2393. IGrouping<TKey, TElement> result;
  2394. return _map.TryGetValue(new Key<TKey>(key), out result) ? result : Enumerable.Empty<TElement>();
  2395. }
  2396. }
  2397. /// <summary>
  2398. /// Determines whether a specified key is in the <see cref="Lookup{TKey,TElement}" />.
  2399. /// </summary>
  2400. public bool Contains(TKey key)
  2401. {
  2402. return _map.ContainsKey(new Key<TKey>(key));
  2403. }
  2404. /// <summary>
  2405. /// Applies a transform function to each key and its associated
  2406. /// values and returns the results.
  2407. /// </summary>
  2408. public IEnumerable<TResult> ApplyResultSelector<TResult>(
  2409. FFunc<TKey, IEnumerable<TElement>, TResult> resultSelector)
  2410. {
  2411. if (resultSelector == null)
  2412. throw new ArgumentNullException("resultSelector");
  2413. foreach (var pair in _map)
  2414. yield return resultSelector(pair.Key.Value, pair.Value);
  2415. }
  2416. /// <summary>
  2417. /// Returns a generic enumerator that iterates through the <see cref="Lookup{TKey,TElement}" />.
  2418. /// </summary>
  2419. public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator()
  2420. {
  2421. foreach (var key in _orderedKeys)
  2422. yield return _map[key];
  2423. }
  2424. IEnumerator IEnumerable.GetEnumerator()
  2425. {
  2426. return GetEnumerator();
  2427. }
  2428. }
  2429. }
  2430. // $Id: OrderedEnumerable.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
  2431. namespace LinqBridge
  2432. {
  2433. #region Imports
  2434. using System;
  2435. using System.Collections;
  2436. using System.Collections.Generic;
  2437. using System.Diagnostics;
  2438. using System.Linq;
  2439. #endregion
  2440. internal sealed class OrderedEnumerable<T, K> : IOrderedEnumerable<T>
  2441. {
  2442. private readonly IEnumerable<T> _source;
  2443. private readonly FFunc<T[], IComparer<int>, IComparer<int>> _comparerComposer;
  2444. public OrderedEnumerable(IEnumerable<T> source,
  2445. FFunc<T, K> keySelector, IComparer<K> comparer, bool descending) :
  2446. this(source, (_, next) => next, keySelector, comparer, descending) { }
  2447. private OrderedEnumerable(IEnumerable<T> source,
  2448. FFunc<T[], IComparer<int>, IComparer<int>> parent,
  2449. FFunc<T, K> keySelector, IComparer<K> comparer, bool descending)
  2450. {
  2451. if (source == null) throw new ArgumentNullException("source");
  2452. if (keySelector == null) throw new ArgumentNullException("keySelector");
  2453. Debug.Assert(parent != null);
  2454. _source = source;
  2455. comparer = comparer ?? Comparer<K>.Default;
  2456. var direction = descending ? -1 : 1;
  2457. _comparerComposer = (items, next) =>
  2458. {
  2459. Debug.Assert(items != null);
  2460. Debug.Assert(next != null);
  2461. var keys = new K[items.Length];
  2462. for (var i = 0; i < items.Length; i++)
  2463. keys[i] = keySelector(items[i]);
  2464. return parent(items, new DelegatingComparer<int>((i, j) =>
  2465. {
  2466. var result = direction * comparer.Compare(keys[i], keys[j]);
  2467. return result != 0 ? result : next.Compare(i, j);
  2468. }));
  2469. };
  2470. }
  2471. public IOrderedEnumerable<T> CreateOrderedEnumerable<KK>(
  2472. FFunc<T, KK> keySelector, IComparer<KK> comparer, bool descending)
  2473. {
  2474. return new OrderedEnumerable<T, KK>(_source, _comparerComposer, keySelector, comparer, descending);
  2475. }
  2476. public IEnumerator<T> GetEnumerator()
  2477. {
  2478. //
  2479. // Sort using Array.Sort but docs say that it performs an
  2480. // unstable sort. LINQ, on the other hand, says OrderBy performs
  2481. // a stable sort. Use the item position then as a tie
  2482. // breaker when all keys compare equal, thus making the sort
  2483. // stable.
  2484. //
  2485. var items = _source.ToArray();
  2486. var positionComparer = new DelegatingComparer<int>((i, j) => i.CompareTo(j));
  2487. var comparer = _comparerComposer(items, positionComparer);
  2488. var keys = new int[items.Length];
  2489. for (var i = 0; i < keys.Length; i++)
  2490. keys[i] = i;
  2491. Array.Sort(keys, items, comparer);
  2492. return ((IEnumerable<T>)items).GetEnumerator();
  2493. }
  2494. IEnumerator IEnumerable.GetEnumerator()
  2495. {
  2496. return GetEnumerator();
  2497. }
  2498. }
  2499. }
  2500. // $Id: Action.cs 71137f497bf2 2012/04/16 20:01:27 azizatif $
  2501. namespace System
  2502. {
  2503. #if LINQBRIDGE_LIB
  2504. public delegate void Action();
  2505. public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
  2506. public delegate void Action<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
  2507. public delegate void Action<in T1, in T2, in T3, in T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
  2508. #else
  2509. public delegate void FsDbAction();
  2510. public delegate void FsDbAction<T1, T2>(T1 arg1, T2 arg2);
  2511. public delegate void FsDbAction<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3);
  2512. public delegate void FsDbAction<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
  2513. #endif
  2514. }