QueryableEx.cs 119 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Globalization;
  5. using System.Linq.Expressions;
  6. using System.Reflection;
  7. namespace System.Linq
  8. {
  9. /// <summary>
  10. /// Provides a set of additional static methods that allow querying enumerable sequences.
  11. /// </summary>
  12. public static class QueryableEx
  13. {
  14. /// <summary>
  15. /// Determines whether an enumerable sequence is empty.
  16. /// </summary>
  17. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  18. /// <param name="source">Source sequence.</param>
  19. /// <returns>true if the sequence is empty; false otherwise.</returns>
  20. public static bool IsEmpty<TSource>(this IQueryable<TSource> source)
  21. {
  22. if (source == null)
  23. throw new ArgumentNullException("source");
  24. return source.Provider.Execute<bool>(
  25. Expression.Call(
  26. null,
  27. #if CRIPPLED_REFLECTION
  28. InfoOf(() => QueryableEx.IsEmpty<TSource>(default(IQueryable<TSource>))),
  29. #else
  30. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  31. #endif
  32. source.Expression
  33. )
  34. );
  35. }
  36. #pragma warning disable 1591
  37. [EditorBrowsable(EditorBrowsableState.Never)]
  38. public static bool IsEmpty<TSource>(IEnumerable<TSource> source)
  39. {
  40. return EnumerableEx.IsEmpty(source);
  41. }
  42. #pragma warning restore 1591
  43. /// <summary>
  44. /// Returns the minimum value in the enumerable sequence by using the specified comparer to compare values.
  45. /// </summary>
  46. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  47. /// <param name="source">Source sequence.</param>
  48. /// <param name="comparer">Comparer used to determine the minimum value.</param>
  49. /// <returns>Minimum value in the sequence.</returns>
  50. public static TSource Min<TSource>(this IQueryable<TSource> source, IComparer<TSource> comparer)
  51. {
  52. if (source == null)
  53. throw new ArgumentNullException("source");
  54. if (comparer == null)
  55. throw new ArgumentNullException("comparer");
  56. return source.Provider.Execute<TSource>(
  57. Expression.Call(
  58. null,
  59. #if CRIPPLED_REFLECTION
  60. InfoOf(() => QueryableEx.Min<TSource>(default(IQueryable<TSource>), default(IComparer<TSource>))),
  61. #else
  62. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  63. #endif
  64. source.Expression,
  65. Expression.Constant(comparer, typeof(IComparer<TSource>))
  66. )
  67. );
  68. }
  69. #pragma warning disable 1591
  70. [EditorBrowsable(EditorBrowsableState.Never)]
  71. public static TSource Min<TSource>(IEnumerable<TSource> source, IComparer<TSource> comparer)
  72. {
  73. return EnumerableEx.Min(source, comparer);
  74. }
  75. #pragma warning restore 1591
  76. /// <summary>
  77. /// Returns the elements with the minimum key value by using the default comparer to compare key values.
  78. /// </summary>
  79. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  80. /// <typeparam name="TKey">Key type.</typeparam>
  81. /// <param name="source">Source sequence.</param>
  82. /// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
  83. /// <returns>List with the elements that share the same minimum key value.</returns>
  84. public static IList<TSource> MinBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
  85. {
  86. if (source == null)
  87. throw new ArgumentNullException("source");
  88. if (keySelector == null)
  89. throw new ArgumentNullException("keySelector");
  90. return source.Provider.Execute<IList<TSource>>(
  91. Expression.Call(
  92. null,
  93. #if CRIPPLED_REFLECTION
  94. InfoOf(() => QueryableEx.MinBy<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>))),
  95. #else
  96. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  97. #endif
  98. source.Expression,
  99. keySelector
  100. )
  101. );
  102. }
  103. #pragma warning disable 1591
  104. [EditorBrowsable(EditorBrowsableState.Never)]
  105. public static IList<TSource> MinBy<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  106. {
  107. return EnumerableEx.MinBy(source, keySelector);
  108. }
  109. #pragma warning restore 1591
  110. /// <summary>
  111. /// Returns the elements with the minimum key value by using the specified comparer to compare key values.
  112. /// </summary>
  113. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  114. /// <typeparam name="TKey">Key type.</typeparam>
  115. /// <param name="source">Source sequence.</param>
  116. /// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
  117. /// <param name="comparer">Comparer used to determine the minimum key value.</param>
  118. /// <returns>List with the elements that share the same minimum key value.</returns>
  119. public static IList<TSource> MinBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
  120. {
  121. if (source == null)
  122. throw new ArgumentNullException("source");
  123. if (keySelector == null)
  124. throw new ArgumentNullException("keySelector");
  125. if (comparer == null)
  126. throw new ArgumentNullException("comparer");
  127. return source.Provider.Execute<IList<TSource>>(
  128. Expression.Call(
  129. null,
  130. #if CRIPPLED_REFLECTION
  131. InfoOf(() => QueryableEx.MinBy<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>))),
  132. #else
  133. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  134. #endif
  135. source.Expression,
  136. keySelector,
  137. Expression.Constant(comparer, typeof(IComparer<TKey>))
  138. )
  139. );
  140. }
  141. #pragma warning disable 1591
  142. [EditorBrowsable(EditorBrowsableState.Never)]
  143. public static IList<TSource> MinBy<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  144. {
  145. return EnumerableEx.MinBy(source, keySelector, comparer);
  146. }
  147. #pragma warning restore 1591
  148. /// <summary>
  149. /// Returns the maximum value in the enumerable sequence by using the specified comparer to compare values.
  150. /// </summary>
  151. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  152. /// <param name="source">Source sequence.</param>
  153. /// <param name="comparer">Comparer used to determine the maximum value.</param>
  154. /// <returns>Maximum value in the sequence.</returns>
  155. public static TSource Max<TSource>(this IQueryable<TSource> source, IComparer<TSource> comparer)
  156. {
  157. if (source == null)
  158. throw new ArgumentNullException("source");
  159. if (comparer == null)
  160. throw new ArgumentNullException("comparer");
  161. return source.Provider.Execute<TSource>(
  162. Expression.Call(
  163. null,
  164. #if CRIPPLED_REFLECTION
  165. InfoOf(() => QueryableEx.Max<TSource>(default(IQueryable<TSource>), default(IComparer<TSource>))),
  166. #else
  167. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  168. #endif
  169. source.Expression,
  170. Expression.Constant(comparer, typeof(IComparer<TSource>))
  171. )
  172. );
  173. }
  174. #pragma warning disable 1591
  175. [EditorBrowsable(EditorBrowsableState.Never)]
  176. public static TSource Max<TSource>(IEnumerable<TSource> source, IComparer<TSource> comparer)
  177. {
  178. return EnumerableEx.Max(source, comparer);
  179. }
  180. #pragma warning restore 1591
  181. /// <summary>
  182. /// Returns the elements with the maximum key value by using the default comparer to compare key values.
  183. /// </summary>
  184. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  185. /// <typeparam name="TKey">Key type.</typeparam>
  186. /// <param name="source">Source sequence.</param>
  187. /// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
  188. /// <returns>List with the elements that share the same maximum key value.</returns>
  189. public static IList<TSource> MaxBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
  190. {
  191. if (source == null)
  192. throw new ArgumentNullException("source");
  193. if (keySelector == null)
  194. throw new ArgumentNullException("keySelector");
  195. return source.Provider.Execute<IList<TSource>>(
  196. Expression.Call(
  197. null,
  198. #if CRIPPLED_REFLECTION
  199. InfoOf(() => QueryableEx.MaxBy<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>))),
  200. #else
  201. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  202. #endif
  203. source.Expression,
  204. keySelector
  205. )
  206. );
  207. }
  208. #pragma warning disable 1591
  209. [EditorBrowsable(EditorBrowsableState.Never)]
  210. public static IList<TSource> MaxBy<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  211. {
  212. return EnumerableEx.MaxBy(source, keySelector);
  213. }
  214. #pragma warning restore 1591
  215. /// <summary>
  216. /// Returns the elements with the minimum key value by using the specified comparer to compare key values.
  217. /// </summary>
  218. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  219. /// <typeparam name="TKey">Key type.</typeparam>
  220. /// <param name="source">Source sequence.</param>
  221. /// <param name="keySelector">Key selector used to extract the key for each element in the sequence.</param>
  222. /// <param name="comparer">Comparer used to determine the maximum key value.</param>
  223. /// <returns>List with the elements that share the same maximum key value.</returns>
  224. public static IList<TSource> MaxBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IComparer<TKey> comparer)
  225. {
  226. if (source == null)
  227. throw new ArgumentNullException("source");
  228. if (keySelector == null)
  229. throw new ArgumentNullException("keySelector");
  230. if (comparer == null)
  231. throw new ArgumentNullException("comparer");
  232. return source.Provider.Execute<IList<TSource>>(
  233. Expression.Call(
  234. null,
  235. #if CRIPPLED_REFLECTION
  236. InfoOf(() => QueryableEx.MaxBy<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IComparer<TKey>))),
  237. #else
  238. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  239. #endif
  240. source.Expression,
  241. keySelector,
  242. Expression.Constant(comparer, typeof(IComparer<TKey>))
  243. )
  244. );
  245. }
  246. #pragma warning disable 1591
  247. [EditorBrowsable(EditorBrowsableState.Never)]
  248. public static IList<TSource> MaxBy<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IComparer<TKey> comparer)
  249. {
  250. return EnumerableEx.MaxBy(source, keySelector, comparer);
  251. }
  252. #pragma warning restore 1591
  253. /// <summary>
  254. /// Shares the source sequence within a selector function where each enumerator can fetch the next element from the source sequence.
  255. /// </summary>
  256. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  257. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  258. /// <param name="source">Source sequence.</param>
  259. /// <param name="selector">Selector function with shared access to the source sequence for each enumerator.</param>
  260. /// <returns>Sequence resulting from applying the selector function to the shared view over the source sequence.</returns>
  261. public static IQueryable<TResult> Share<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>> selector)
  262. {
  263. if (source == null)
  264. throw new ArgumentNullException("source");
  265. if (selector == null)
  266. throw new ArgumentNullException("selector");
  267. return source.Provider.CreateQuery<TResult>(
  268. Expression.Call(
  269. null,
  270. #if CRIPPLED_REFLECTION
  271. InfoOf(() => QueryableEx.Share<TSource, TResult>(default(IQueryable<TSource>), default(Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>>))),
  272. #else
  273. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)),
  274. #endif
  275. source.Expression,
  276. selector
  277. )
  278. );
  279. }
  280. #pragma warning disable 1591
  281. [EditorBrowsable(EditorBrowsableState.Never)]
  282. public static IEnumerable<TResult> Share<TSource, TResult>(IEnumerable<TSource> source, Func<IEnumerable<TSource>, IEnumerable<TResult>> selector)
  283. {
  284. return EnumerableEx.Share(source, selector);
  285. }
  286. #pragma warning restore 1591
  287. /// <summary>
  288. /// Publishes the source sequence within a selector function where each enumerator can obtain a view over a tail of the source sequence.
  289. /// </summary>
  290. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  291. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  292. /// <param name="source">Source sequence.</param>
  293. /// <param name="selector">Selector function with published access to the source sequence for each enumerator.</param>
  294. /// <returns>Sequence resulting from applying the selector function to the published view over the source sequence.</returns>
  295. public static IQueryable<TResult> Publish<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>> selector)
  296. {
  297. if (source == null)
  298. throw new ArgumentNullException("source");
  299. if (selector == null)
  300. throw new ArgumentNullException("selector");
  301. return source.Provider.CreateQuery<TResult>(
  302. Expression.Call(
  303. null,
  304. #if CRIPPLED_REFLECTION
  305. InfoOf(() => QueryableEx.Publish<TSource, TResult>(default(IQueryable<TSource>), default(Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>>))),
  306. #else
  307. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)),
  308. #endif
  309. source.Expression,
  310. selector
  311. )
  312. );
  313. }
  314. #pragma warning disable 1591
  315. [EditorBrowsable(EditorBrowsableState.Never)]
  316. public static IEnumerable<TResult> Publish<TSource, TResult>(IEnumerable<TSource> source, Func<IEnumerable<TSource>, IEnumerable<TResult>> selector)
  317. {
  318. return EnumerableEx.Publish(source, selector);
  319. }
  320. #pragma warning restore 1591
  321. /// <summary>
  322. /// Memoizes the source sequence within a selector function where each enumerator can get access to all of the sequence's elements without causing multiple enumerations over the source.
  323. /// </summary>
  324. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  325. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  326. /// <param name="source">Source sequence.</param>
  327. /// <param name="selector">Selector function with memoized access to the source sequence for each enumerator.</param>
  328. /// <returns>Sequence resulting from applying the selector function to the memoized view over the source sequence.</returns>
  329. public static IQueryable<TResult> Memoize<TSource, TResult>(this IQueryable<TSource> source, Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>> selector)
  330. {
  331. if (source == null)
  332. throw new ArgumentNullException("source");
  333. if (selector == null)
  334. throw new ArgumentNullException("selector");
  335. return source.Provider.CreateQuery<TResult>(
  336. Expression.Call(
  337. null,
  338. #if CRIPPLED_REFLECTION
  339. InfoOf(() => QueryableEx.Memoize<TSource, TResult>(default(IQueryable<TSource>), default(Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>>))),
  340. #else
  341. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)),
  342. #endif
  343. source.Expression,
  344. selector
  345. )
  346. );
  347. }
  348. #pragma warning disable 1591
  349. [EditorBrowsable(EditorBrowsableState.Never)]
  350. public static IEnumerable<TResult> Memoize<TSource, TResult>(IEnumerable<TSource> source, Func<IEnumerable<TSource>, IEnumerable<TResult>> selector)
  351. {
  352. return EnumerableEx.Memoize(source, selector);
  353. }
  354. #pragma warning restore 1591
  355. /// <summary>
  356. /// Memoizes the source sequence within a selector function where a specified number of enumerators can get access to all of the sequence's elements without causing multiple enumerations over the source.
  357. /// </summary>
  358. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  359. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  360. /// <param name="source">Source sequence.</param>
  361. /// <param name="readerCount">Number of enumerators that can access the underlying buffer. Once every enumerator has obtained an element from the buffer, the element is removed from the buffer.</param>
  362. /// <param name="selector">Selector function with memoized access to the source sequence for a specified number of enumerators.</param>
  363. /// <returns>Sequence resulting from applying the selector function to the memoized view over the source sequence.</returns>
  364. public static IQueryable<TResult> Memoize<TSource, TResult>(this IQueryable<TSource> source, int readerCount, Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>> selector)
  365. {
  366. if (source == null)
  367. throw new ArgumentNullException("source");
  368. if (selector == null)
  369. throw new ArgumentNullException("selector");
  370. return source.Provider.CreateQuery<TResult>(
  371. Expression.Call(
  372. null,
  373. #if CRIPPLED_REFLECTION
  374. InfoOf(() => QueryableEx.Memoize<TSource, TResult>(default(IQueryable<TSource>), default(int), default(Expression<Func<IEnumerable<TSource>, IEnumerable<TResult>>>))),
  375. #else
  376. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)),
  377. #endif
  378. source.Expression,
  379. Expression.Constant(readerCount, typeof(int)),
  380. selector
  381. )
  382. );
  383. }
  384. #pragma warning disable 1591
  385. [EditorBrowsable(EditorBrowsableState.Never)]
  386. public static IEnumerable<TResult> Memoize<TSource, TResult>(IEnumerable<TSource> source, int readerCount, Func<IEnumerable<TSource>, IEnumerable<TResult>> selector)
  387. {
  388. return EnumerableEx.Memoize(source, readerCount, selector);
  389. }
  390. #pragma warning restore 1591
  391. /// <summary>
  392. /// Creates an enumerable sequence based on an enumerator factory function.
  393. /// </summary>
  394. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  395. /// <param name="provider">Query provider.</param>
  396. /// <param name="getEnumerator">Enumerator factory function.</param>
  397. /// <returns>Sequence that will invoke the enumerator factory upon a call to GetEnumerator.</returns>
  398. public static IQueryable<TResult> Create<TResult>(this IQueryProvider provider, Expression<Func<IEnumerator<TResult>>> getEnumerator)
  399. {
  400. if (provider == null)
  401. throw new ArgumentNullException("provider");
  402. if (getEnumerator == null)
  403. throw new ArgumentNullException("getEnumerator");
  404. return provider.CreateQuery<TResult>(
  405. Expression.Call(
  406. null,
  407. #if CRIPPLED_REFLECTION
  408. InfoOf(() => QueryableEx.Create<TResult>(default(IQueryProvider), default(Expression<Func<IEnumerator<TResult>>>))),
  409. #else
  410. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  411. #endif
  412. Expression.Constant(provider, typeof(IQueryProvider)),
  413. getEnumerator
  414. )
  415. );
  416. }
  417. #pragma warning disable 1591
  418. [EditorBrowsable(EditorBrowsableState.Never)]
  419. public static IEnumerable<TResult> Create<TResult>(Func<IEnumerator<TResult>> getEnumerator)
  420. {
  421. return EnumerableEx.Create(getEnumerator);
  422. }
  423. #pragma warning restore 1591
  424. /// <summary>
  425. /// Returns a sequence with a single element.
  426. /// </summary>
  427. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  428. /// <param name="provider">Query provider.</param>
  429. /// <param name="value">Single element of the resulting sequence.</param>
  430. /// <returns>Sequence with a single element.</returns>
  431. public static IQueryable<TResult> Return<TResult>(this IQueryProvider provider, TResult value)
  432. {
  433. if (provider == null)
  434. throw new ArgumentNullException("provider");
  435. return provider.CreateQuery<TResult>(
  436. Expression.Call(
  437. null,
  438. #if CRIPPLED_REFLECTION
  439. InfoOf(() => QueryableEx.Return<TResult>(default(IQueryProvider), default(TResult))),
  440. #else
  441. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  442. #endif
  443. Expression.Constant(provider, typeof(IQueryProvider)),
  444. Expression.Constant(value, typeof(TResult))
  445. )
  446. );
  447. }
  448. #pragma warning disable 1591
  449. [EditorBrowsable(EditorBrowsableState.Never)]
  450. public static /*!*/IQueryable<TResult> Return<TResult>(TResult value)
  451. {
  452. return EnumerableEx.Return(value).AsQueryable();
  453. }
  454. #pragma warning restore 1591
  455. /// <summary>
  456. /// Returns a sequence that throws an exception upon enumeration.
  457. /// </summary>
  458. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  459. /// <param name="provider">Query provider.</param>
  460. /// <param name="exception">Exception to throw upon enumerating the resulting sequence.</param>
  461. /// <returns>Sequence that throws the specified exception upon enumeration.</returns>
  462. public static IQueryable<TResult> Throw<TResult>(this IQueryProvider provider, Exception exception)
  463. {
  464. if (provider == null)
  465. throw new ArgumentNullException("provider");
  466. if (exception == null)
  467. throw new ArgumentNullException("exception");
  468. return provider.CreateQuery<TResult>(
  469. Expression.Call(
  470. null,
  471. #if CRIPPLED_REFLECTION
  472. InfoOf(() => QueryableEx.Throw<TResult>(default(IQueryProvider), default(Exception))),
  473. #else
  474. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  475. #endif
  476. Expression.Constant(provider, typeof(IQueryProvider)),
  477. Expression.Constant(exception, typeof(Exception))
  478. )
  479. );
  480. }
  481. #pragma warning disable 1591
  482. [EditorBrowsable(EditorBrowsableState.Never)]
  483. public static /*!*/IQueryable<TResult> Throw<TResult>(Exception exception)
  484. {
  485. return EnumerableEx.Throw<TResult>(exception).AsQueryable();
  486. }
  487. #pragma warning restore 1591
  488. /// <summary>
  489. /// Creates an enumerable sequence based on an enumerable factory function.
  490. /// </summary>
  491. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  492. /// <param name="provider">Query provider.</param>
  493. /// <param name="enumerableFactory">Enumerable factory function.</param>
  494. /// <returns>Sequence that will invoke the enumerable factory upon a call to GetEnumerator.</returns>
  495. public static IQueryable<TResult> Defer<TResult>(this IQueryProvider provider, Expression<Func<IEnumerable<TResult>>> enumerableFactory)
  496. {
  497. if (provider == null)
  498. throw new ArgumentNullException("provider");
  499. if (enumerableFactory == null)
  500. throw new ArgumentNullException("enumerableFactory");
  501. return provider.CreateQuery<TResult>(
  502. Expression.Call(
  503. null,
  504. #if CRIPPLED_REFLECTION
  505. InfoOf(() => QueryableEx.Defer<TResult>(default(IQueryProvider), default(Expression<Func<IEnumerable<TResult>>>))),
  506. #else
  507. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  508. #endif
  509. Expression.Constant(provider, typeof(IQueryProvider)),
  510. enumerableFactory
  511. )
  512. );
  513. }
  514. #pragma warning disable 1591
  515. [EditorBrowsable(EditorBrowsableState.Never)]
  516. public static /*!*/IQueryable<TResult> Defer<TResult>(Func<IEnumerable<TResult>> enumerableFactory)
  517. {
  518. return EnumerableEx.Defer(enumerableFactory).AsQueryable();
  519. }
  520. #pragma warning restore 1591
  521. /// <summary>
  522. /// Generates a sequence by mimicking a for loop.
  523. /// </summary>
  524. /// <typeparam name="TState">State type.</typeparam>
  525. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  526. /// <param name="provider">Query provider.</param>
  527. /// <param name="initialState">Initial state of the generator loop.</param>
  528. /// <param name="condition">Loop condition.</param>
  529. /// <param name="iterate">State update function to run after every iteration of the generator loop.</param>
  530. /// <param name="resultSelector">Result selector to compute resulting sequence elements.</param>
  531. /// <returns>Sequence obtained by running the generator loop, yielding computed elements.</returns>
  532. public static IQueryable<TResult> Generate<TState, TResult>(this IQueryProvider provider, TState initialState, Expression<Func<TState, bool>> condition, Expression<Func<TState, TState>> iterate, Expression<Func<TState, TResult>> resultSelector)
  533. {
  534. if (provider == null)
  535. throw new ArgumentNullException("provider");
  536. if (condition == null)
  537. throw new ArgumentNullException("condition");
  538. if (iterate == null)
  539. throw new ArgumentNullException("iterate");
  540. if (resultSelector == null)
  541. throw new ArgumentNullException("resultSelector");
  542. return provider.CreateQuery<TResult>(
  543. Expression.Call(
  544. null,
  545. #if CRIPPLED_REFLECTION
  546. InfoOf(() => QueryableEx.Generate<TState, TResult>(default(IQueryProvider), default(TState), default(Expression<Func<TState, bool>>), default(Expression<Func<TState, TState>>), default(Expression<Func<TState, TResult>>))),
  547. #else
  548. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TState), typeof(TResult)),
  549. #endif
  550. Expression.Constant(provider, typeof(IQueryProvider)),
  551. Expression.Constant(initialState),
  552. condition,
  553. iterate,
  554. resultSelector
  555. )
  556. );
  557. }
  558. #pragma warning disable 1591
  559. [EditorBrowsable(EditorBrowsableState.Never)]
  560. public static /*!*/IQueryable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector)
  561. {
  562. return EnumerableEx.Generate(initialState, condition, iterate, resultSelector).AsQueryable();
  563. }
  564. #pragma warning restore 1591
  565. /// <summary>
  566. /// Generates a sequence that's dependent on a resource object whose lifetime is determined by the sequence usage duration.
  567. /// </summary>
  568. /// <typeparam name="TSource">Source element type.</typeparam>
  569. /// <typeparam name="TResource">Resource type.</typeparam>
  570. /// <param name="provider">Query provider.</param>
  571. /// <param name="resourceFactory">Resource factory function.</param>
  572. /// <param name="enumerableFactory">Enumerable factory function, having access to the obtained resource.</param>
  573. /// <returns>Sequence whose use controls the lifetime of the associated obtained resource.</returns>
  574. public static IQueryable<TSource> Using<TSource, TResource>(this IQueryProvider provider, Expression<Func<TResource>> resourceFactory, Expression<Func<TResource, IEnumerable<TSource>>> enumerableFactory) where TResource : IDisposable
  575. {
  576. if (provider == null)
  577. throw new ArgumentNullException("provider");
  578. if (resourceFactory == null)
  579. throw new ArgumentNullException("resourceFactory");
  580. if (enumerableFactory == null)
  581. throw new ArgumentNullException("enumerableFactory");
  582. return provider.CreateQuery<TSource>(
  583. Expression.Call(
  584. null,
  585. #if CRIPPLED_REFLECTION
  586. InfoOf(() => QueryableEx.Using<TSource, TResource>(default(IQueryProvider), default(Expression<Func<TResource>>), default(Expression<Func<TResource, IEnumerable<TSource>>>))),
  587. #else
  588. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResource)),
  589. #endif
  590. Expression.Constant(provider, typeof(IQueryProvider)),
  591. resourceFactory,
  592. enumerableFactory
  593. )
  594. );
  595. }
  596. #pragma warning disable 1591
  597. [EditorBrowsable(EditorBrowsableState.Never)]
  598. public static /*!*/IQueryable<TSource> Using<TSource, TResource>(Func<TResource> resourceFactory, Func<TResource, IEnumerable<TSource>> enumerableFactory) where TResource : IDisposable
  599. {
  600. return EnumerableEx.Using(resourceFactory, enumerableFactory).AsQueryable();
  601. }
  602. #pragma warning restore 1591
  603. /// <summary>
  604. /// Generates a sequence by repeating the given value infinitely.
  605. /// </summary>
  606. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  607. /// <param name="provider">Query provider.</param>
  608. /// <param name="value">Value to repreat in the resulting sequence.</param>
  609. /// <returns>Sequence repeating the given value infinitely.</returns>
  610. public static IEnumerable<TResult> Repeat<TResult>(this IQueryProvider provider, TResult value)
  611. {
  612. if (provider == null)
  613. throw new ArgumentNullException("provider");
  614. return provider.CreateQuery<TResult>(
  615. Expression.Call(
  616. null,
  617. #if CRIPPLED_REFLECTION
  618. InfoOf(() => QueryableEx.Repeat<TResult>(default(IQueryProvider), default(TResult))),
  619. #else
  620. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  621. #endif
  622. Expression.Constant(provider, typeof(IQueryProvider)),
  623. Expression.Constant(value, typeof(TResult))
  624. )
  625. );
  626. }
  627. #pragma warning disable 1591
  628. [EditorBrowsable(EditorBrowsableState.Never)]
  629. public static /*!*/IQueryable<TResult> Repeat<TResult>(TResult value)
  630. {
  631. return EnumerableEx.Repeat(value).AsQueryable();
  632. }
  633. #pragma warning restore 1591
  634. /// <summary>
  635. /// Creates a sequence that corresponds to the source sequence, concatenating it with the sequence resulting from calling an exception handler function in case of an error.
  636. /// </summary>
  637. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  638. /// <typeparam name="TException">Exception type to catch.</typeparam>
  639. /// <param name="source">Source sequence.</param>
  640. /// <param name="handler">Handler to invoke when an exception of the specified type occurs.</param>
  641. /// <returns>Source sequence, concatenated with an exception handler result sequence in case of an error.</returns>
  642. public static IQueryable<TSource> Catch<TSource, TException>(this IQueryable<TSource> source, Expression<Func<TException, IEnumerable<TSource>>> handler)
  643. where TException : Exception
  644. {
  645. if (source == null)
  646. throw new ArgumentNullException("source");
  647. if (handler == null)
  648. throw new ArgumentNullException("handler");
  649. return source.Provider.CreateQuery<TSource>(
  650. Expression.Call(
  651. null,
  652. #if CRIPPLED_REFLECTION
  653. InfoOf(() => QueryableEx.Catch<TSource, TException>(default(IQueryable<TSource>), default(Expression<Func<TException, IEnumerable<TSource>>>))),
  654. #else
  655. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TException)),
  656. #endif
  657. source.Expression,
  658. handler
  659. )
  660. );
  661. }
  662. #pragma warning disable 1591
  663. [EditorBrowsable(EditorBrowsableState.Never)]
  664. public static IEnumerable<TSource> Catch<TSource, TException>(IEnumerable<TSource> source, Func<TException, IEnumerable<TSource>> handler)
  665. where TException : Exception
  666. {
  667. return EnumerableEx.Catch(source, handler);
  668. }
  669. #pragma warning restore 1591
  670. /// <summary>
  671. /// Creates a sequence by concatenating source sequences until a source sequence completes successfully.
  672. /// </summary>
  673. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  674. /// <param name="sources">Source sequences.</param>
  675. /// <returns>Sequence that continues to concatenate source sequences while errors occur.</returns>
  676. public static IQueryable<TSource> Catch<TSource>(this IQueryable<IEnumerable<TSource>> sources)
  677. {
  678. if (sources == null)
  679. throw new ArgumentNullException("sources");
  680. return sources.Provider.CreateQuery<TSource>(
  681. Expression.Call(
  682. null,
  683. #if CRIPPLED_REFLECTION
  684. InfoOf(() => QueryableEx.Catch<TSource>(default(IQueryable<IEnumerable<TSource>>))),
  685. #else
  686. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  687. #endif
  688. sources.Expression
  689. )
  690. );
  691. }
  692. #pragma warning disable 1591
  693. [EditorBrowsable(EditorBrowsableState.Never)]
  694. public static IEnumerable<TSource> Catch<TSource>(IEnumerable<IEnumerable<TSource>> sources)
  695. {
  696. return EnumerableEx.Catch(sources);
  697. }
  698. #pragma warning restore 1591
  699. /// <summary>
  700. /// Creates a sequence by concatenating source sequences until a source sequence completes successfully.
  701. /// </summary>
  702. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  703. /// <param name="provider">Query provider.</param>
  704. /// <param name="sources">Source sequences.</param>
  705. /// <returns>Sequence that continues to concatenate source sequences while errors occur.</returns>
  706. public static IQueryable<TSource> Catch<TSource>(this IQueryProvider provider, params IEnumerable<TSource>[] sources)
  707. {
  708. if (provider == null)
  709. throw new ArgumentNullException("provider");
  710. if (sources == null)
  711. throw new ArgumentNullException("sources");
  712. return provider.CreateQuery<TSource>(
  713. Expression.Call(
  714. null,
  715. #if CRIPPLED_REFLECTION
  716. InfoOf(() => QueryableEx.Catch<TSource>(default(IQueryProvider), default(IEnumerable<TSource>[]))),
  717. #else
  718. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  719. #endif
  720. Expression.Constant(provider, typeof(IQueryProvider)),
  721. GetSourceExpression(sources)
  722. )
  723. );
  724. }
  725. #pragma warning disable 1591
  726. [EditorBrowsable(EditorBrowsableState.Never)]
  727. public static /*!*/IQueryable<TSource> Catch<TSource>(params IEnumerable<TSource>[] sources)
  728. {
  729. return EnumerableEx.Catch(sources).AsQueryable();
  730. }
  731. #pragma warning restore 1591
  732. /// <summary>
  733. /// Creates a sequence that returns the elements of the first sequence, switching to the second in case of an error.
  734. /// </summary>
  735. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  736. /// <param name="first">First sequence.</param>
  737. /// <param name="second">Second sequence, concatenated to the result in case the first sequence completes exceptionally.</param>
  738. /// <returns>The first sequence, followed by the second sequence in case an error is produced.</returns>
  739. public static IQueryable<TSource> Catch<TSource>(this IQueryable<TSource> first, IEnumerable<TSource> second)
  740. {
  741. if (first == null)
  742. throw new ArgumentNullException("first");
  743. if (second == null)
  744. throw new ArgumentNullException("second");
  745. return first.Provider.CreateQuery<TSource>(
  746. Expression.Call(
  747. null,
  748. #if CRIPPLED_REFLECTION
  749. InfoOf(() => QueryableEx.Catch<TSource>(default(IQueryable<TSource>), default(IEnumerable<TSource>))),
  750. #else
  751. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  752. #endif
  753. first.Expression,
  754. GetSourceExpression(second)
  755. )
  756. );
  757. }
  758. #pragma warning disable 1591
  759. [EditorBrowsable(EditorBrowsableState.Never)]
  760. public static IEnumerable<TSource> Catch<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second)
  761. {
  762. return EnumerableEx.Catch(first, second);
  763. }
  764. #pragma warning restore 1591
  765. /// <summary>
  766. /// Creates a sequence whose termination or disposal of an enumerator causes a finally action to be executed.
  767. /// </summary>
  768. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  769. /// <param name="source">Source sequence.</param>
  770. /// <param name="finallyAction">Action to run upon termination of the sequence, or when an enumerator is disposed.</param>
  771. /// <returns>Source sequence with guarantees on the invocation of the finally action.</returns>
  772. public static IQueryable<TSource> Finally<TSource>(this IQueryable<TSource> source, Expression<Action> finallyAction)
  773. {
  774. if (source == null)
  775. throw new ArgumentNullException("source");
  776. if (finallyAction == null)
  777. throw new ArgumentNullException("finallyAction");
  778. return source.Provider.CreateQuery<TSource>(
  779. Expression.Call(
  780. null,
  781. #if CRIPPLED_REFLECTION
  782. InfoOf(() => QueryableEx.Finally<TSource>(default(IQueryable<TSource>), default(Expression<Action>))),
  783. #else
  784. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  785. #endif
  786. source.Expression,
  787. finallyAction
  788. )
  789. );
  790. }
  791. #pragma warning disable 1591
  792. [EditorBrowsable(EditorBrowsableState.Never)]
  793. public static IEnumerable<TSource> Finally<TSource>(IEnumerable<TSource> source, Action finallyAction)
  794. {
  795. return EnumerableEx.Finally(source, finallyAction);
  796. }
  797. #pragma warning restore 1591
  798. /// <summary>
  799. /// Creates a sequence that concatenates both given sequences, regardless of whether an error occurs.
  800. /// </summary>
  801. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  802. /// <param name="first">First sequence.</param>
  803. /// <param name="second">Second sequence.</param>
  804. /// <returns>Sequence concatenating the elements of both sequences, ignoring errors.</returns>
  805. public static IQueryable<TSource> OnErrorResumeNext<TSource>(this IQueryable<TSource> first, IEnumerable<TSource> second)
  806. {
  807. if (first == null)
  808. throw new ArgumentNullException("first");
  809. if (second == null)
  810. throw new ArgumentNullException("second");
  811. return first.Provider.CreateQuery<TSource>(
  812. Expression.Call(
  813. null,
  814. #if CRIPPLED_REFLECTION
  815. InfoOf(() => QueryableEx.OnErrorResumeNext<TSource>(default(IQueryable<TSource>), default(IEnumerable<TSource>))),
  816. #else
  817. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  818. #endif
  819. first.Expression,
  820. GetSourceExpression(second)
  821. )
  822. );
  823. }
  824. #pragma warning disable 1591
  825. [EditorBrowsable(EditorBrowsableState.Never)]
  826. public static IEnumerable<TSource> OnErrorResumeNext<TSource>(IEnumerable<TSource> first, IEnumerable<TSource> second)
  827. {
  828. return EnumerableEx.OnErrorResumeNext(first, second);
  829. }
  830. #pragma warning restore 1591
  831. /// <summary>
  832. /// Creates a sequence that concatenates the given sequences, regardless of whether an error occurs in any of the sequences.
  833. /// </summary>
  834. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  835. /// <param name="provider">Query provider.</param>
  836. /// <param name="sources">Source sequences.</param>
  837. /// <returns>Sequence concatenating the elements of the given sequences, ignoring errors.</returns>
  838. public static IEnumerable<TSource> OnErrorResumeNext<TSource>(this IQueryProvider provider, params IEnumerable<TSource>[] sources)
  839. {
  840. if (provider == null)
  841. throw new ArgumentNullException("provider");
  842. if (sources == null)
  843. throw new ArgumentNullException("sources");
  844. return provider.CreateQuery<TSource>(
  845. Expression.Call(
  846. null,
  847. #if CRIPPLED_REFLECTION
  848. InfoOf(() => QueryableEx.OnErrorResumeNext<TSource>(default(IQueryProvider), default(IEnumerable<TSource>[]))),
  849. #else
  850. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  851. #endif
  852. Expression.Constant(provider, typeof(IQueryProvider)),
  853. GetSourceExpression(sources)
  854. )
  855. );
  856. }
  857. #pragma warning disable 1591
  858. [EditorBrowsable(EditorBrowsableState.Never)]
  859. public static /*!*/IQueryable<TSource> OnErrorResumeNext<TSource>(params IEnumerable<TSource>[] sources)
  860. {
  861. return EnumerableEx.OnErrorResumeNext(sources).AsQueryable();
  862. }
  863. #pragma warning restore 1591
  864. /// <summary>
  865. /// Creates a sequence that concatenates the given sequences, regardless of whether an error occurs in any of the sequences.
  866. /// </summary>
  867. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  868. /// <param name="sources">Source sequences.</param>
  869. /// <returns>Sequence concatenating the elements of the given sequences, ignoring errors.</returns>
  870. public static IQueryable<TSource> OnErrorResumeNext<TSource>(this IQueryable<IEnumerable<TSource>> sources)
  871. {
  872. if (sources == null)
  873. throw new ArgumentNullException("sources");
  874. return sources.Provider.CreateQuery<TSource>(
  875. Expression.Call(
  876. null,
  877. #if CRIPPLED_REFLECTION
  878. InfoOf(() => QueryableEx.OnErrorResumeNext<TSource>(default(IQueryable<IEnumerable<TSource>>))),
  879. #else
  880. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  881. #endif
  882. sources.Expression
  883. )
  884. );
  885. }
  886. #pragma warning disable 1591
  887. [EditorBrowsable(EditorBrowsableState.Never)]
  888. public static IEnumerable<TSource> OnErrorResumeNext<TSource>(IEnumerable<IEnumerable<TSource>> sources)
  889. {
  890. return EnumerableEx.OnErrorResumeNext(sources);
  891. }
  892. #pragma warning restore 1591
  893. /// <summary>
  894. /// Creates a sequence that retries enumerating the source sequence as long as an error occurs.
  895. /// </summary>
  896. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  897. /// <param name="source">Source sequence.</param>
  898. /// <returns>Sequence concatenating the results of the source sequence as long as an error occurs.</returns>
  899. public static IQueryable<TSource> Retry<TSource>(this IQueryable<TSource> source)
  900. {
  901. if (source == null)
  902. throw new ArgumentNullException("source");
  903. return source.Provider.CreateQuery<TSource>(
  904. Expression.Call(
  905. null,
  906. #if CRIPPLED_REFLECTION
  907. InfoOf(() => QueryableEx.Retry<TSource>(default(IQueryable<TSource>))),
  908. #else
  909. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  910. #endif
  911. source.Expression
  912. )
  913. );
  914. }
  915. #pragma warning disable 1591
  916. [EditorBrowsable(EditorBrowsableState.Never)]
  917. public static IEnumerable<TSource> Retry<TSource>(IEnumerable<TSource> source)
  918. {
  919. return EnumerableEx.Retry(source);
  920. }
  921. #pragma warning restore 1591
  922. /// <summary>
  923. /// Creates a sequence that retries enumerating the source sequence as long as an error occurs, with the specified maximum number of retries.
  924. /// </summary>
  925. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  926. /// <param name="source">Source sequence.</param>
  927. /// <param name="retryCount">Maximum number of retries.</param>
  928. /// <returns>Sequence concatenating the results of the source sequence as long as an error occurs.</returns>
  929. public static IQueryable<TSource> Retry<TSource>(this IQueryable<TSource> source, int retryCount)
  930. {
  931. if (source == null)
  932. throw new ArgumentNullException("source");
  933. return source.Provider.CreateQuery<TSource>(
  934. Expression.Call(
  935. null,
  936. #if CRIPPLED_REFLECTION
  937. InfoOf(() => QueryableEx.Retry<TSource>(default(IQueryable<TSource>), default(int))),
  938. #else
  939. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  940. #endif
  941. source.Expression,
  942. Expression.Constant(retryCount, typeof(int))
  943. )
  944. );
  945. }
  946. #pragma warning disable 1591
  947. [EditorBrowsable(EditorBrowsableState.Never)]
  948. public static IEnumerable<TSource> Retry<TSource>(IEnumerable<TSource> source, int retryCount)
  949. {
  950. return EnumerableEx.Retry(source, retryCount);
  951. }
  952. #pragma warning restore 1591
  953. /// <summary>
  954. /// Generates an enumerable sequence by repeating a source sequence as long as the given loop condition holds.
  955. /// </summary>
  956. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  957. /// <param name="provider">Query provider.</param>
  958. /// <param name="condition">Loop condition.</param>
  959. /// <param name="source">Sequence to repeat while the condition evaluates true.</param>
  960. /// <returns>Sequence generated by repeating the given sequence while the condition evaluates to true.</returns>
  961. public static IQueryable<TResult> While<TResult>(this IQueryProvider provider, Expression<Func<bool>> condition, IEnumerable<TResult> source)
  962. {
  963. if (provider == null)
  964. throw new ArgumentNullException("provider");
  965. if (condition == null)
  966. throw new ArgumentNullException("condition");
  967. if (source == null)
  968. throw new ArgumentNullException("source");
  969. return provider.CreateQuery<TResult>(
  970. Expression.Call(
  971. null,
  972. #if CRIPPLED_REFLECTION
  973. InfoOf(() => QueryableEx.While<TResult>(default(IQueryProvider), default(Expression<Func<bool>>), default(IEnumerable<TResult>))),
  974. #else
  975. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  976. #endif
  977. Expression.Constant(provider, typeof(IQueryProvider)),
  978. condition,
  979. GetSourceExpression(source)
  980. )
  981. );
  982. }
  983. #pragma warning disable 1591
  984. [EditorBrowsable(EditorBrowsableState.Never)]
  985. public static /*!*/IQueryable<TResult> While<TResult>(Func<bool> condition, IEnumerable<TResult> source)
  986. {
  987. return EnumerableEx.While(condition, source).AsQueryable();
  988. }
  989. #pragma warning restore 1591
  990. /// <summary>
  991. /// Returns an enumerable sequence based on the evaluation result of the given condition.
  992. /// </summary>
  993. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  994. /// <param name="provider">Query provider.</param>
  995. /// <param name="condition">Condition to evaluate.</param>
  996. /// <param name="thenSource">Sequence to return in case the condition evaluates true.</param>
  997. /// <param name="elseSource">Sequence to return in case the condition evaluates false.</param>
  998. /// <returns>Either of the two input sequences based on the result of evaluating the condition.</returns>
  999. public static IQueryable<TResult> If<TResult>(this IQueryProvider provider, Expression<Func<bool>> condition, IEnumerable<TResult> thenSource, IEnumerable<TResult> elseSource)
  1000. {
  1001. if (provider == null)
  1002. throw new ArgumentNullException("provider");
  1003. if (condition == null)
  1004. throw new ArgumentNullException("condition");
  1005. if (thenSource == null)
  1006. throw new ArgumentNullException("thenSource");
  1007. if (elseSource == null)
  1008. throw new ArgumentNullException("elseSource");
  1009. return provider.CreateQuery<TResult>(
  1010. Expression.Call(
  1011. null,
  1012. #if CRIPPLED_REFLECTION
  1013. InfoOf(() => QueryableEx.If<TResult>(default(IQueryProvider), default(Expression<Func<bool>>), default(IEnumerable<TResult>), default(IEnumerable<TResult>))),
  1014. #else
  1015. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  1016. #endif
  1017. Expression.Constant(provider, typeof(IQueryProvider)),
  1018. condition,
  1019. GetSourceExpression(thenSource),
  1020. GetSourceExpression(elseSource)
  1021. )
  1022. );
  1023. }
  1024. #pragma warning disable 1591
  1025. [EditorBrowsable(EditorBrowsableState.Never)]
  1026. public static /*!*/IQueryable<TResult> If<TResult>(Func<bool> condition, IEnumerable<TResult> thenSource, IEnumerable<TResult> elseSource)
  1027. {
  1028. return EnumerableEx.If(condition, thenSource, elseSource).AsQueryable();
  1029. }
  1030. #pragma warning restore 1591
  1031. /// <summary>
  1032. /// Returns an enumerable sequence if the evaluation result of the given condition is true, otherwise returns an empty sequence.
  1033. /// </summary>
  1034. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  1035. /// <param name="provider">Query provider.</param>
  1036. /// <param name="condition">Condition to evaluate.</param>
  1037. /// <param name="thenSource">Sequence to return in case the condition evaluates true.</param>
  1038. /// <returns>The given input sequence if the condition evaluates true; otherwise, an empty sequence.</returns>
  1039. public static IQueryable<TResult> If<TResult>(this IQueryProvider provider, Expression<Func<bool>> condition, IEnumerable<TResult> thenSource)
  1040. {
  1041. if (provider == null)
  1042. throw new ArgumentNullException("provider");
  1043. if (condition == null)
  1044. throw new ArgumentNullException("condition");
  1045. if (thenSource == null)
  1046. throw new ArgumentNullException("thenSource");
  1047. return provider.CreateQuery<TResult>(
  1048. Expression.Call(
  1049. null,
  1050. #if CRIPPLED_REFLECTION
  1051. InfoOf(() => QueryableEx.If<TResult>(default(IQueryProvider), default(Expression<Func<bool>>), default(IEnumerable<TResult>))),
  1052. #else
  1053. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  1054. #endif
  1055. Expression.Constant(provider, typeof(IQueryProvider)),
  1056. condition,
  1057. GetSourceExpression(thenSource)
  1058. )
  1059. );
  1060. }
  1061. #pragma warning disable 1591
  1062. [EditorBrowsable(EditorBrowsableState.Never)]
  1063. public static /*!*/IQueryable<TResult> If<TResult>(Func<bool> condition, IEnumerable<TResult> thenSource)
  1064. {
  1065. return EnumerableEx.If(condition, thenSource).AsQueryable();
  1066. }
  1067. #pragma warning restore 1591
  1068. /// <summary>
  1069. /// Generates an enumerable sequence by repeating a source sequence as long as the given loop postcondition holds.
  1070. /// </summary>
  1071. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  1072. /// <param name="source">Source sequence to repeat while the condition evaluates true.</param>
  1073. /// <param name="condition">Loop condition.</param>
  1074. /// <returns>Sequence generated by repeating the given sequence until the condition evaluates to false.</returns>
  1075. public static IQueryable<TResult> DoWhile<TResult>(this IQueryable<TResult> source, Expression<Func<bool>> condition)
  1076. {
  1077. if (source == null)
  1078. throw new ArgumentNullException("source");
  1079. if (condition == null)
  1080. throw new ArgumentNullException("condition");
  1081. return source.Provider.CreateQuery<TResult>(
  1082. Expression.Call(
  1083. null,
  1084. #if CRIPPLED_REFLECTION
  1085. InfoOf(() => QueryableEx.DoWhile<TResult>(default(IQueryable<TResult>), default(Expression<Func<bool>>))),
  1086. #else
  1087. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  1088. #endif
  1089. source.Expression,
  1090. condition
  1091. )
  1092. );
  1093. }
  1094. #pragma warning disable 1591
  1095. [EditorBrowsable(EditorBrowsableState.Never)]
  1096. public static IEnumerable<TResult> DoWhile<TResult>(IEnumerable<TResult> source, Func<bool> condition)
  1097. {
  1098. return EnumerableEx.DoWhile(source, condition);
  1099. }
  1100. #pragma warning restore 1591
  1101. /// <summary>
  1102. /// Returns a sequence from a dictionary based on the result of evaluating a selector function.
  1103. /// </summary>
  1104. /// <typeparam name="TValue">Type of the selector value.</typeparam>
  1105. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  1106. /// <param name="provider">Query provider.</param>
  1107. /// <param name="selector">Selector function used to pick a sequence from the given sources.</param>
  1108. /// <param name="sources">Dictionary mapping selector values onto resulting sequences.</param>
  1109. /// <returns>The source sequence corresponding with the evaluated selector value; otherwise, an empty sequence.</returns>
  1110. public static IQueryable<TResult> Case<TValue, TResult>(this IQueryProvider provider, Expression<Func<TValue>> selector, IDictionary<TValue, IEnumerable<TResult>> sources)
  1111. {
  1112. if (provider == null)
  1113. throw new ArgumentNullException("provider");
  1114. if (selector == null)
  1115. throw new ArgumentNullException("selector");
  1116. if (sources == null)
  1117. throw new ArgumentNullException("sources");
  1118. return provider.CreateQuery<TResult>(
  1119. Expression.Call(
  1120. null,
  1121. #if CRIPPLED_REFLECTION
  1122. InfoOf(() => QueryableEx.Case<TValue, TResult>(default(IQueryProvider), default(Expression<Func<TValue>>), default(IDictionary<TValue, IEnumerable<TResult>>))),
  1123. #else
  1124. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TValue), typeof(TResult)),
  1125. #endif
  1126. selector,
  1127. Expression.Constant(sources, typeof(IDictionary<TValue, IEnumerable<TResult>>))
  1128. )
  1129. );
  1130. }
  1131. #pragma warning disable 1591
  1132. [EditorBrowsable(EditorBrowsableState.Never)]
  1133. public static /*!*/IQueryable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IEnumerable<TResult>> sources)
  1134. {
  1135. return EnumerableEx.Case(selector, sources).AsQueryable();
  1136. }
  1137. #pragma warning restore 1591
  1138. /// <summary>
  1139. /// Returns a sequence from a dictionary based on the result of evaluating a selector function, also specifying a default sequence.
  1140. /// </summary>
  1141. /// <typeparam name="TValue">Type of the selector value.</typeparam>
  1142. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  1143. /// <param name="provider">Query provider.</param>
  1144. /// <param name="selector">Selector function used to pick a sequence from the given sources.</param>
  1145. /// <param name="sources">Dictionary mapping selector values onto resulting sequences.</param>
  1146. /// <param name="defaultSource">Default sequence to return in case there's no corresponding source for the computed selector value.</param>
  1147. /// <returns>The source sequence corresponding with the evaluated selector value; otherwise, the default source.</returns>
  1148. public static IQueryable<TResult> Case<TValue, TResult>(this IQueryProvider provider, Expression<Func<TValue>> selector, IDictionary<TValue, IEnumerable<TResult>> sources, IEnumerable<TResult> defaultSource)
  1149. {
  1150. if (provider == null)
  1151. throw new ArgumentNullException("provider");
  1152. if (selector == null)
  1153. throw new ArgumentNullException("selector");
  1154. if (sources == null)
  1155. throw new ArgumentNullException("sources");
  1156. if (defaultSource == null)
  1157. throw new ArgumentNullException("defaultSource");
  1158. return provider.CreateQuery<TResult>(
  1159. Expression.Call(
  1160. null,
  1161. #if CRIPPLED_REFLECTION
  1162. InfoOf(() => QueryableEx.Case<TValue, TResult>(default(IQueryProvider), default(Expression<Func<TValue>>), default(IDictionary<TValue, IEnumerable<TResult>>), default(IEnumerable<TResult>))),
  1163. #else
  1164. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TValue), typeof(TResult)),
  1165. #endif
  1166. selector,
  1167. Expression.Constant(sources, typeof(IDictionary<TValue, IEnumerable<TResult>>))
  1168. )
  1169. );
  1170. }
  1171. #pragma warning disable 1591
  1172. [EditorBrowsable(EditorBrowsableState.Never)]
  1173. public static /*!*/IQueryable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IEnumerable<TResult>> sources, IEnumerable<TResult> defaultSource)
  1174. {
  1175. return EnumerableEx.Case(selector, sources, defaultSource).AsQueryable();
  1176. }
  1177. #pragma warning restore 1591
  1178. /// <summary>
  1179. /// Generates a sequence by enumerating a source sequence, mapping its elements on result sequences, and concatenating those sequences.
  1180. /// </summary>
  1181. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1182. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  1183. /// <param name="provider">Query provider.</param>
  1184. /// <param name="source">Source sequence.</param>
  1185. /// <param name="resultSelector">Result selector to evaluate for each iteration over the source.</param>
  1186. /// <returns>Sequence concatenating the inner sequences that result from evaluating the result selector on elements from the source.</returns>
  1187. public static IQueryable<TResult> For<TSource, TResult>(this IQueryProvider provider, IEnumerable<TSource> source, Expression<Func<TSource, IEnumerable<TResult>>> resultSelector)
  1188. {
  1189. if (provider == null)
  1190. throw new ArgumentNullException("provider");
  1191. if (source == null)
  1192. throw new ArgumentNullException("source");
  1193. if (resultSelector == null)
  1194. throw new ArgumentNullException("resultSelector");
  1195. return provider.CreateQuery<TResult>(
  1196. Expression.Call(
  1197. null,
  1198. #if CRIPPLED_REFLECTION
  1199. InfoOf(() => QueryableEx.For<TSource, TResult>(default(IQueryProvider), default(IEnumerable<TSource>), default(Expression<Func<TSource, IEnumerable<TResult>>>))),
  1200. #else
  1201. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TResult)),
  1202. #endif
  1203. GetSourceExpression(source),
  1204. resultSelector
  1205. )
  1206. );
  1207. }
  1208. #pragma warning disable 1591
  1209. [EditorBrowsable(EditorBrowsableState.Never)]
  1210. public static /*!*/IQueryable<TResult> For<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> resultSelector)
  1211. {
  1212. return EnumerableEx.For(source, resultSelector).AsQueryable();
  1213. }
  1214. #pragma warning restore 1591
  1215. /// <summary>
  1216. /// Concatenates the input sequences.
  1217. /// </summary>
  1218. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1219. /// <param name="sources">Source sequences.</param>
  1220. /// <returns>Sequence with the elements of the source sequences concatenated.</returns>
  1221. public static IQueryable<TSource> Concat<TSource>(this IQueryable<IEnumerable<TSource>> sources)
  1222. {
  1223. if (sources == null)
  1224. throw new ArgumentNullException("sources");
  1225. return sources.Provider.CreateQuery<TSource>(
  1226. Expression.Call(
  1227. null,
  1228. #if CRIPPLED_REFLECTION
  1229. InfoOf(() => QueryableEx.Concat<TSource>(default(IQueryable<IEnumerable<TSource>>))),
  1230. #else
  1231. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1232. #endif
  1233. GetSourceExpression(sources)
  1234. )
  1235. );
  1236. }
  1237. #pragma warning disable 1591
  1238. [EditorBrowsable(EditorBrowsableState.Never)]
  1239. public static IEnumerable<TSource> Concat<TSource>(IEnumerable<IEnumerable<TSource>> sources)
  1240. {
  1241. return EnumerableEx.Concat(sources);
  1242. }
  1243. #pragma warning restore 1591
  1244. /// <summary>
  1245. /// Concatenates the input sequences.
  1246. /// </summary>
  1247. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1248. /// <param name="provider">Query provider.</param>
  1249. /// <param name="sources">Source sequences.</param>
  1250. /// <returns>Sequence with the elements of the source sequences concatenated.</returns>
  1251. public static IQueryable<TSource> Concat<TSource>(this IQueryProvider provider, params IEnumerable<TSource>[] sources)
  1252. {
  1253. if (provider == null)
  1254. throw new ArgumentNullException("provider");
  1255. if (sources == null)
  1256. throw new ArgumentNullException("sources");
  1257. return provider.CreateQuery<TSource>(
  1258. Expression.Call(
  1259. null,
  1260. #if CRIPPLED_REFLECTION
  1261. InfoOf(() => QueryableEx.Concat<TSource>(default(IQueryProvider), default(IEnumerable<TSource>[]))),
  1262. #else
  1263. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1264. #endif
  1265. Expression.Constant(provider, typeof(IQueryProvider)),
  1266. GetSourceExpression(sources)
  1267. )
  1268. );
  1269. }
  1270. #pragma warning disable 1591
  1271. [EditorBrowsable(EditorBrowsableState.Never)]
  1272. public static /*!*/IQueryable<TSource> Concat<TSource>(params IEnumerable<TSource>[] sources)
  1273. {
  1274. return EnumerableEx.Concat(sources).AsQueryable();
  1275. }
  1276. #pragma warning restore 1591
  1277. /// <summary>
  1278. /// Projects each element of a sequence to an given sequence and flattens the resulting sequences into one sequence.
  1279. /// </summary>
  1280. /// <typeparam name="TSource">First source sequence element type.</typeparam>
  1281. /// <typeparam name="TOther">Second source sequence element type.</typeparam>
  1282. /// <param name="source">A sequence of values to project.</param>
  1283. /// <param name="other">Inner sequence each source sequenec element is projected onto.</param>
  1284. /// <returns>Sequence flattening the sequences that result from projecting elements in the source sequence.</returns>
  1285. public static IQueryable<TOther> SelectMany<TSource, TOther>(this IQueryable<TSource> source, IEnumerable<TOther> other)
  1286. {
  1287. if (source == null)
  1288. throw new ArgumentNullException("source");
  1289. if (other == null)
  1290. throw new ArgumentNullException("other");
  1291. return source.Provider.CreateQuery<TOther>(
  1292. Expression.Call(
  1293. null,
  1294. #if CRIPPLED_REFLECTION
  1295. InfoOf(() => QueryableEx.SelectMany<TSource, TOther>(default(IQueryable<TSource>), default(IEnumerable<TOther>))),
  1296. #else
  1297. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TOther)),
  1298. #endif
  1299. source.Expression,
  1300. GetSourceExpression(other)
  1301. )
  1302. );
  1303. }
  1304. #pragma warning disable 1591
  1305. [EditorBrowsable(EditorBrowsableState.Never)]
  1306. public static IEnumerable<TOther> SelectMany<TSource, TOther>(IEnumerable<TSource> source, IEnumerable<TOther> other)
  1307. {
  1308. return EnumerableEx.SelectMany(source, other);
  1309. }
  1310. #pragma warning restore 1591
  1311. #if NO_ZIP
  1312. /// <summary>
  1313. /// Merges two sequences by applying the specified selector function on index-based corresponding element pairs from both sequences.
  1314. /// </summary>
  1315. /// <typeparam name="TFirst">The type of the elements of the first input sequence.</typeparam>
  1316. /// <typeparam name="TSecond">The type of the elements of the second input sequence.</typeparam>
  1317. /// <typeparam name="TResult">The type of the elements of the result sequence.</typeparam>
  1318. /// <param name="first">The first sequence to merge.</param>
  1319. /// <param name="second">The second sequence to merge.</param>
  1320. /// <param name="resultSelector">Function to apply to each pair of elements from both sequences.</param>
  1321. /// <returns>Sequence consisting of the result of pairwise application of the selector function over pairs of elements from the source sequences.</returns>
  1322. public static IQueryable<TResult> Zip<TFirst, TSecond, TResult>(this IQueryable<TFirst> first, IEnumerable<TSecond> second, Expression<Func<TFirst, TSecond, TResult>> resultSelector)
  1323. {
  1324. if (first == null)
  1325. throw new ArgumentNullException("first");
  1326. if (second == null)
  1327. throw new ArgumentNullException("second");
  1328. if (resultSelector == null)
  1329. throw new ArgumentNullException("resultSelector");
  1330. return first.Provider.CreateQuery<TResult>(
  1331. Expression.Call(
  1332. null,
  1333. #if CRIPPLED_REFLECTION
  1334. InfoOf(() => QueryableEx.Zip<TFirst, TSecond, TResult>(default(IQueryable<TFirst>), default(IEnumerable<TSecond>), default(Expression<Func<TFirst, TSecond, TResult>>))),
  1335. #else
  1336. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TFirst), typeof(TSecond), typeof(TResult)),
  1337. #endif
  1338. first.Expression,
  1339. GetSourceExpression(second),
  1340. resultSelector
  1341. )
  1342. );
  1343. }
  1344. #pragma warning disable 1591
  1345. [EditorBrowsable(EditorBrowsableState.Never)]
  1346. public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> resultSelector)
  1347. {
  1348. return EnumerableEx.Zip(first, second, resultSelector);
  1349. }
  1350. #pragma warning restore 1591
  1351. #endif
  1352. /// <summary>
  1353. /// Hides the enumerable sequence object identity.
  1354. /// </summary>
  1355. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1356. /// <param name="source">Source sequence.</param>
  1357. /// <returns>Enumerable sequence with the same behavior as the original, but hiding the source object identity.</returns>
  1358. /// <remarks>AsQueryable doesn't hide the object identity, and simply acts as a cast to the IQueryable&lt;TSource&gt; interface.</remarks>
  1359. public static IQueryable<TSource> Hide<TSource>(this IQueryable<TSource> source)
  1360. {
  1361. if (source == null)
  1362. throw new ArgumentNullException("source");
  1363. return source.Provider.CreateQuery<TSource>(
  1364. Expression.Call(
  1365. null,
  1366. #if CRIPPLED_REFLECTION
  1367. InfoOf(() => QueryableEx.Hide<TSource>(default(IQueryable<TSource>))),
  1368. #else
  1369. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1370. #endif
  1371. source.Expression
  1372. )
  1373. );
  1374. }
  1375. #pragma warning disable 1591
  1376. [EditorBrowsable(EditorBrowsableState.Never)]
  1377. public static IEnumerable<TSource> Hide<TSource>(IEnumerable<TSource> source)
  1378. {
  1379. return EnumerableEx.Hide(source);
  1380. }
  1381. #pragma warning restore 1591
  1382. /// <summary>
  1383. /// Lazily invokes an action for each value in the sequence.
  1384. /// </summary>
  1385. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1386. /// <param name="source">Source sequence.</param>
  1387. /// <param name="onNext">Action to invoke for each element.</param>
  1388. /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>
  1389. public static IQueryable<TSource> Do<TSource>(this IQueryable<TSource> source, Expression<Action<TSource>> onNext)
  1390. {
  1391. if (source == null)
  1392. throw new ArgumentNullException("source");
  1393. if (onNext == null)
  1394. throw new ArgumentNullException("onNext");
  1395. return source.Provider.CreateQuery<TSource>(
  1396. Expression.Call(
  1397. null,
  1398. #if CRIPPLED_REFLECTION
  1399. InfoOf(() => QueryableEx.Do<TSource>(default(IQueryable<TSource>), default(Expression<Action<TSource>>))),
  1400. #else
  1401. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1402. #endif
  1403. source.Expression,
  1404. onNext
  1405. )
  1406. );
  1407. }
  1408. #pragma warning disable 1591
  1409. [EditorBrowsable(EditorBrowsableState.Never)]
  1410. public static IEnumerable<TSource> Do<TSource>(IEnumerable<TSource> source, Action<TSource> onNext)
  1411. {
  1412. return EnumerableEx.Do(source, onNext);
  1413. }
  1414. #pragma warning restore 1591
  1415. /// <summary>
  1416. /// Lazily invokes an action for each value in the sequence, and executes an action for successful termination.
  1417. /// </summary>
  1418. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1419. /// <param name="source">Source sequence.</param>
  1420. /// <param name="onNext">Action to invoke for each element.</param>
  1421. /// <param name="onCompleted">Action to invoke on successful termination of the sequence.</param>
  1422. /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>
  1423. public static IQueryable<TSource> Do<TSource>(this IQueryable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action> onCompleted)
  1424. {
  1425. if (source == null)
  1426. throw new ArgumentNullException("source");
  1427. if (onNext == null)
  1428. throw new ArgumentNullException("onNext");
  1429. if (onCompleted == null)
  1430. throw new ArgumentNullException("onCompleted");
  1431. return source.Provider.CreateQuery<TSource>(
  1432. Expression.Call(
  1433. null,
  1434. #if CRIPPLED_REFLECTION
  1435. InfoOf(() => QueryableEx.Do<TSource>(default(IQueryable<TSource>), default(Expression<Action<TSource>>), default(Expression<Action>))),
  1436. #else
  1437. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1438. #endif
  1439. source.Expression,
  1440. onNext,
  1441. onCompleted
  1442. )
  1443. );
  1444. }
  1445. #pragma warning disable 1591
  1446. [EditorBrowsable(EditorBrowsableState.Never)]
  1447. public static IEnumerable<TSource> Do<TSource>(IEnumerable<TSource> source, Action<TSource> onNext, Action onCompleted)
  1448. {
  1449. return EnumerableEx.Do(source, onNext, onCompleted);
  1450. }
  1451. #pragma warning restore 1591
  1452. /// <summary>
  1453. /// Lazily invokes an action for each value in the sequence, and executes an action upon exceptional termination.
  1454. /// </summary>
  1455. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1456. /// <param name="source">Source sequence.</param>
  1457. /// <param name="onNext">Action to invoke for each element.</param>
  1458. /// <param name="onError">Action to invoke on exceptional termination of the sequence.</param>
  1459. /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>
  1460. public static IQueryable<TSource> Do<TSource>(this IQueryable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action<Exception>> onError)
  1461. {
  1462. if (source == null)
  1463. throw new ArgumentNullException("source");
  1464. if (onNext == null)
  1465. throw new ArgumentNullException("onNext");
  1466. if (onError == null)
  1467. throw new ArgumentNullException("onError");
  1468. return source.Provider.CreateQuery<TSource>(
  1469. Expression.Call(
  1470. null,
  1471. #if CRIPPLED_REFLECTION
  1472. InfoOf(() => QueryableEx.Do<TSource>(default(IQueryable<TSource>), default(Expression<Action<TSource>>), default(Expression<Action<Exception>>))),
  1473. #else
  1474. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1475. #endif
  1476. source.Expression,
  1477. onNext,
  1478. onError
  1479. )
  1480. );
  1481. }
  1482. #pragma warning disable 1591
  1483. [EditorBrowsable(EditorBrowsableState.Never)]
  1484. public static IEnumerable<TSource> Do<TSource>(IEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError)
  1485. {
  1486. return EnumerableEx.Do(source, onNext, onError);
  1487. }
  1488. #pragma warning restore 1591
  1489. /// <summary>
  1490. /// Lazily invokes an action for each value in the sequence, and executes an action upon successful or exceptional termination.
  1491. /// </summary>
  1492. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1493. /// <param name="source">Source sequence.</param>
  1494. /// <param name="onNext">Action to invoke for each element.</param>
  1495. /// <param name="onError">Action to invoke on exceptional termination of the sequence.</param>
  1496. /// <param name="onCompleted">Action to invoke on successful termination of the sequence.</param>
  1497. /// <returns>Sequence exhibiting the specified side-effects upon enumeration.</returns>
  1498. public static IQueryable<TSource> Do<TSource>(this IQueryable<TSource> source, Expression<Action<TSource>> onNext, Expression<Action<Exception>> onError, Expression<Action> onCompleted)
  1499. {
  1500. if (source == null)
  1501. throw new ArgumentNullException("source");
  1502. if (onNext == null)
  1503. throw new ArgumentNullException("onNext");
  1504. if (onError == null)
  1505. throw new ArgumentNullException("onError");
  1506. if (onCompleted == null)
  1507. throw new ArgumentNullException("onCompleted");
  1508. return source.Provider.CreateQuery<TSource>(
  1509. Expression.Call(
  1510. null,
  1511. #if CRIPPLED_REFLECTION
  1512. InfoOf(() => QueryableEx.Do<TSource>(default(IQueryable<TSource>), default(Expression<Action<TSource>>), default(Expression<Action<Exception>>), default(Expression<Action>))),
  1513. #else
  1514. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1515. #endif
  1516. source.Expression,
  1517. onNext,
  1518. onError,
  1519. onCompleted
  1520. )
  1521. );
  1522. }
  1523. #pragma warning disable 1591
  1524. [EditorBrowsable(EditorBrowsableState.Never)]
  1525. public static IEnumerable<TSource> Do<TSource>(IEnumerable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
  1526. {
  1527. return EnumerableEx.Do(source, onNext, onError, onCompleted);
  1528. }
  1529. #pragma warning restore 1591
  1530. #if !NO_RXINTERFACES
  1531. /// <summary>
  1532. /// Lazily invokes observer methods for each value in the sequence, and upon successful or exceptional termination.
  1533. /// </summary>
  1534. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1535. /// <param name="source">Source sequence.</param>
  1536. /// <param name="observer">Observer to invoke notification calls on.</param>
  1537. /// <returns>Sequence exhibiting the side-effects of observer method invocation upon enumeration.</returns>
  1538. public static IQueryable<TSource> Do<TSource>(this IQueryable<TSource> source, IObserver<TSource> observer)
  1539. {
  1540. if (source == null)
  1541. throw new ArgumentNullException("source");
  1542. if (observer == null)
  1543. throw new ArgumentNullException("observer");
  1544. return source.Provider.CreateQuery<TSource>(
  1545. Expression.Call(
  1546. null,
  1547. #if CRIPPLED_REFLECTION
  1548. InfoOf(() => QueryableEx.Do<TSource>(default(IQueryable<TSource>), default(IObserver<TSource>))),
  1549. #else
  1550. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1551. #endif
  1552. source.Expression,
  1553. Expression.Constant(observer, typeof(IObserver<TSource>))
  1554. )
  1555. );
  1556. }
  1557. #pragma warning disable 1591
  1558. [EditorBrowsable(EditorBrowsableState.Never)]
  1559. public static IEnumerable<TSource> Do<TSource>(IEnumerable<TSource> source, IObserver<TSource> observer)
  1560. {
  1561. return EnumerableEx.Do(source, observer);
  1562. }
  1563. #pragma warning restore 1591
  1564. #endif
  1565. /// <summary>
  1566. /// Generates a sequence of non-overlapping adjacent buffers over the source sequence.
  1567. /// </summary>
  1568. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1569. /// <param name="source">Source sequence.</param>
  1570. /// <param name="count">Number of elements for allocated buffers.</param>
  1571. /// <returns>Sequence of buffers containing source sequence elements.</returns>
  1572. public static IQueryable<IList<TSource>> Buffer<TSource>(this IQueryable<TSource> source, int count)
  1573. {
  1574. if (source == null)
  1575. throw new ArgumentNullException("source");
  1576. return source.Provider.CreateQuery<IList<TSource>>(
  1577. Expression.Call(
  1578. null,
  1579. #if CRIPPLED_REFLECTION
  1580. InfoOf(() => QueryableEx.Buffer<TSource>(default(IQueryable<TSource>), default(int))),
  1581. #else
  1582. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1583. #endif
  1584. source.Expression,
  1585. Expression.Constant(count, typeof(int))
  1586. )
  1587. );
  1588. }
  1589. #pragma warning disable 1591
  1590. [EditorBrowsable(EditorBrowsableState.Never)]
  1591. public static IEnumerable<IList<TSource>> Buffer<TSource>(IEnumerable<TSource> source, int count)
  1592. {
  1593. return EnumerableEx.Buffer(source, count);
  1594. }
  1595. #pragma warning restore 1591
  1596. /// <summary>
  1597. /// Generates a sequence of buffers over the source sequence, with specified length and possible overlap.
  1598. /// </summary>
  1599. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1600. /// <param name="source">Source sequence.</param>
  1601. /// <param name="count">Number of elements for allocated buffers.</param>
  1602. /// <param name="skip">Number of elements to skip between the start of consecutive buffers.</param>
  1603. /// <returns>Sequence of buffers containing source sequence elements.</returns>
  1604. public static IQueryable<IList<TSource>> Buffer<TSource>(this IQueryable<TSource> source, int count, int skip)
  1605. {
  1606. if (source == null)
  1607. throw new ArgumentNullException("source");
  1608. return source.Provider.CreateQuery<IList<TSource>>(
  1609. Expression.Call(
  1610. null,
  1611. #if CRIPPLED_REFLECTION
  1612. InfoOf(() => QueryableEx.Buffer<TSource>(default(IQueryable<TSource>), default(int), default(int))),
  1613. #else
  1614. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1615. #endif
  1616. source.Expression,
  1617. Expression.Constant(count, typeof(int)),
  1618. Expression.Constant(skip, typeof(int))
  1619. )
  1620. );
  1621. }
  1622. #pragma warning disable 1591
  1623. [EditorBrowsable(EditorBrowsableState.Never)]
  1624. public static IEnumerable<IList<TSource>> Buffer<TSource>(IEnumerable<TSource> source, int count, int skip)
  1625. {
  1626. return EnumerableEx.Buffer(source, count, skip);
  1627. }
  1628. #pragma warning restore 1591
  1629. /// <summary>
  1630. /// Ignores all elements in the source sequence.
  1631. /// </summary>
  1632. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1633. /// <param name="source">Source sequence.</param>
  1634. /// <returns>Source sequence without its elements.</returns>
  1635. public static IQueryable<TSource> IgnoreElements<TSource>(this IQueryable<TSource> source)
  1636. {
  1637. if (source == null)
  1638. throw new ArgumentNullException("source");
  1639. return source.Provider.CreateQuery<TSource>(
  1640. Expression.Call(
  1641. null,
  1642. #if CRIPPLED_REFLECTION
  1643. InfoOf(() => QueryableEx.IgnoreElements<TSource>(default(IQueryable<TSource>))),
  1644. #else
  1645. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1646. #endif
  1647. source.Expression
  1648. )
  1649. );
  1650. }
  1651. #pragma warning disable 1591
  1652. [EditorBrowsable(EditorBrowsableState.Never)]
  1653. public static IEnumerable<TSource> IgnoreElements<TSource>(IEnumerable<TSource> source)
  1654. {
  1655. return EnumerableEx.IgnoreElements(source);
  1656. }
  1657. #pragma warning restore 1591
  1658. /// <summary>
  1659. /// Returns elements with a distinct key value by using the default equality comparer to compare key values.
  1660. /// </summary>
  1661. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1662. /// <typeparam name="TKey">Key type.</typeparam>
  1663. /// <param name="source">Source sequence.</param>
  1664. /// <param name="keySelector">Key selector.</param>
  1665. /// <returns>Sequence that contains the elements from the source sequence with distinct key values.</returns>
  1666. public static IQueryable<TSource> Distinct<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
  1667. {
  1668. if (source == null)
  1669. throw new ArgumentNullException("source");
  1670. if (keySelector == null)
  1671. throw new ArgumentNullException("keySelector");
  1672. return source.Provider.CreateQuery<TSource>(
  1673. Expression.Call(
  1674. null,
  1675. #if CRIPPLED_REFLECTION
  1676. InfoOf(() => QueryableEx.Distinct<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>))),
  1677. #else
  1678. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  1679. #endif
  1680. source.Expression,
  1681. keySelector
  1682. )
  1683. );
  1684. }
  1685. #pragma warning disable 1591
  1686. [EditorBrowsable(EditorBrowsableState.Never)]
  1687. public static IEnumerable<TSource> Distinct<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  1688. {
  1689. return EnumerableEx.Distinct(source, keySelector);
  1690. }
  1691. #pragma warning restore 1591
  1692. /// <summary>
  1693. /// Returns elements with a distinct key value by using the specified equality comparer to compare key values.
  1694. /// </summary>
  1695. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1696. /// <typeparam name="TKey">Key type.</typeparam>
  1697. /// <param name="source">Source sequence.</param>
  1698. /// <param name="keySelector">Key selector.</param>
  1699. /// <param name="comparer">Comparer used to compare key values.</param>
  1700. /// <returns>Sequence that contains the elements from the source sequence with distinct key values.</returns>
  1701. public static IQueryable<TSource> Distinct<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
  1702. {
  1703. if (source == null)
  1704. throw new ArgumentNullException("source");
  1705. if (keySelector == null)
  1706. throw new ArgumentNullException("keySelector");
  1707. if (comparer == null)
  1708. throw new ArgumentNullException("comparer");
  1709. return source.Provider.CreateQuery<TSource>(
  1710. Expression.Call(
  1711. null,
  1712. #if CRIPPLED_REFLECTION
  1713. InfoOf(() => QueryableEx.Distinct<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IEqualityComparer<TKey>))),
  1714. #else
  1715. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  1716. #endif
  1717. source.Expression,
  1718. keySelector,
  1719. Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))
  1720. )
  1721. );
  1722. }
  1723. #pragma warning disable 1591
  1724. [EditorBrowsable(EditorBrowsableState.Never)]
  1725. public static IEnumerable<TSource> Distinct<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
  1726. {
  1727. return EnumerableEx.Distinct(source, keySelector, comparer);
  1728. }
  1729. #pragma warning restore 1591
  1730. /// <summary>
  1731. /// Returns consecutive distinct elements by using the default equality comparer to compare values.
  1732. /// </summary>
  1733. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1734. /// <param name="source">Source sequence.</param>
  1735. /// <returns>Sequence without adjacent non-distinct elements.</returns>
  1736. public static IQueryable<TSource> DistinctUntilChanged<TSource>(this IQueryable<TSource> source)
  1737. {
  1738. if (source == null)
  1739. throw new ArgumentNullException("source");
  1740. return source.Provider.CreateQuery<TSource>(
  1741. Expression.Call(
  1742. null,
  1743. #if CRIPPLED_REFLECTION
  1744. InfoOf(() => QueryableEx.DistinctUntilChanged<TSource>(default(IQueryable<TSource>))),
  1745. #else
  1746. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1747. #endif
  1748. source.Expression
  1749. )
  1750. );
  1751. }
  1752. #pragma warning disable 1591
  1753. [EditorBrowsable(EditorBrowsableState.Never)]
  1754. public static IEnumerable<TSource> DistinctUntilChanged<TSource>(IEnumerable<TSource> source)
  1755. {
  1756. return EnumerableEx.DistinctUntilChanged(source);
  1757. }
  1758. #pragma warning restore 1591
  1759. /// <summary>
  1760. /// Returns consecutive distinct elements by using the specified equality comparer to compare values.
  1761. /// </summary>
  1762. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1763. /// <param name="source">Source sequence.</param>
  1764. /// <param name="comparer">Comparer used to compare values.</param>
  1765. /// <returns>Sequence without adjacent non-distinct elements.</returns>
  1766. public static IQueryable<TSource> DistinctUntilChanged<TSource>(this IQueryable<TSource> source, IEqualityComparer<TSource> comparer)
  1767. {
  1768. if (source == null)
  1769. throw new ArgumentNullException("source");
  1770. if (comparer == null)
  1771. throw new ArgumentNullException("comparer");
  1772. return source.Provider.CreateQuery<TSource>(
  1773. Expression.Call(
  1774. null,
  1775. #if CRIPPLED_REFLECTION
  1776. InfoOf(() => QueryableEx.DistinctUntilChanged<TSource>(default(IQueryable<TSource>), default(IEqualityComparer<TSource>))),
  1777. #else
  1778. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1779. #endif
  1780. source.Expression,
  1781. Expression.Constant(comparer, typeof(IEqualityComparer<TSource>))
  1782. )
  1783. );
  1784. }
  1785. #pragma warning disable 1591
  1786. [EditorBrowsable(EditorBrowsableState.Never)]
  1787. public static IEnumerable<TSource> DistinctUntilChanged<TSource>(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
  1788. {
  1789. return EnumerableEx.DistinctUntilChanged(source, comparer);
  1790. }
  1791. #pragma warning restore 1591
  1792. /// <summary>
  1793. /// Returns consecutive distinct elements based on a key value by using the specified equality comparer to compare key values.
  1794. /// </summary>
  1795. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1796. /// <typeparam name="TKey">Key type.</typeparam>
  1797. /// <param name="source">Source sequence.</param>
  1798. /// <param name="keySelector">Key selector.</param>
  1799. /// <returns>Sequence without adjacent non-distinct elements.</returns>
  1800. public static IQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
  1801. {
  1802. if (source == null)
  1803. throw new ArgumentNullException("source");
  1804. if (keySelector == null)
  1805. throw new ArgumentNullException("keySelector");
  1806. return source.Provider.CreateQuery<TSource>(
  1807. Expression.Call(
  1808. null,
  1809. #if CRIPPLED_REFLECTION
  1810. InfoOf(() => QueryableEx.DistinctUntilChanged<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>))),
  1811. #else
  1812. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  1813. #endif
  1814. source.Expression,
  1815. keySelector
  1816. )
  1817. );
  1818. }
  1819. #pragma warning disable 1591
  1820. [EditorBrowsable(EditorBrowsableState.Never)]
  1821. public static IEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
  1822. {
  1823. return EnumerableEx.DistinctUntilChanged(source, keySelector);
  1824. }
  1825. #pragma warning restore 1591
  1826. /// <summary>
  1827. /// Returns consecutive distinct elements based on a key value by using the specified equality comparer to compare key values.
  1828. /// </summary>
  1829. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1830. /// <typeparam name="TKey">Key type.</typeparam>
  1831. /// <param name="source">Source sequence.</param>
  1832. /// <param name="keySelector">Key selector.</param>
  1833. /// <param name="comparer">Comparer used to compare key values.</param>
  1834. /// <returns>Sequence without adjacent non-distinct elements.</returns>
  1835. public static IQueryable<TSource> DistinctUntilChanged<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, IEqualityComparer<TKey> comparer)
  1836. {
  1837. if (source == null)
  1838. throw new ArgumentNullException("source");
  1839. if (keySelector == null)
  1840. throw new ArgumentNullException("keySelector");
  1841. if (comparer == null)
  1842. throw new ArgumentNullException("comparer");
  1843. return source.Provider.CreateQuery<TSource>(
  1844. Expression.Call(
  1845. null,
  1846. #if CRIPPLED_REFLECTION
  1847. InfoOf(() => QueryableEx.DistinctUntilChanged<TSource, TKey>(default(IQueryable<TSource>), default(Expression<Func<TSource, TKey>>), default(IEqualityComparer<TKey>))),
  1848. #else
  1849. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TKey)),
  1850. #endif
  1851. source.Expression,
  1852. keySelector,
  1853. Expression.Constant(comparer, typeof(IEqualityComparer<TKey>))
  1854. )
  1855. );
  1856. }
  1857. #pragma warning disable 1591
  1858. [EditorBrowsable(EditorBrowsableState.Never)]
  1859. public static IEnumerable<TSource> DistinctUntilChanged<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
  1860. {
  1861. return EnumerableEx.DistinctUntilChanged(source, keySelector, comparer);
  1862. }
  1863. #pragma warning restore 1591
  1864. /// <summary>
  1865. /// Expands the sequence by recursively applying a selector function.
  1866. /// </summary>
  1867. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1868. /// <param name="source">Source sequence.</param>
  1869. /// <param name="selector">Selector function to retrieve the next sequence to expand.</param>
  1870. /// <returns>Sequence with results from the recursive expansion of the source sequence.</returns>
  1871. public static IQueryable<TSource> Expand<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, IEnumerable<TSource>>> selector)
  1872. {
  1873. if (source == null)
  1874. throw new ArgumentNullException("source");
  1875. if (selector == null)
  1876. throw new ArgumentNullException("selector");
  1877. return source.Provider.CreateQuery<TSource>(
  1878. Expression.Call(
  1879. null,
  1880. #if CRIPPLED_REFLECTION
  1881. InfoOf(() => QueryableEx.Expand<TSource>(default(IQueryable<TSource>), default(Expression<Func<TSource, IEnumerable<TSource>>>))),
  1882. #else
  1883. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1884. #endif
  1885. source.Expression,
  1886. selector
  1887. )
  1888. );
  1889. }
  1890. #pragma warning disable 1591
  1891. [EditorBrowsable(EditorBrowsableState.Never)]
  1892. public static IEnumerable<TSource> Expand<TSource>(IEnumerable<TSource> source, Func<TSource, IEnumerable<TSource>> selector)
  1893. {
  1894. return EnumerableEx.Expand(source, selector);
  1895. }
  1896. #pragma warning restore 1591
  1897. /// <summary>
  1898. /// Returns the source sequence prefixed with the specified value.
  1899. /// </summary>
  1900. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1901. /// <param name="source">Source sequence.</param>
  1902. /// <param name="values">Values to prefix the sequence with.</param>
  1903. /// <returns>Sequence starting with the specified prefix value, followed by the source sequence.</returns>
  1904. public static IQueryable<TSource> StartWith<TSource>(this IQueryable<TSource> source, params TSource[] values)
  1905. {
  1906. if (source == null)
  1907. throw new ArgumentNullException("source");
  1908. return source.Provider.CreateQuery<TSource>(
  1909. Expression.Call(
  1910. null,
  1911. #if CRIPPLED_REFLECTION
  1912. InfoOf(() => QueryableEx.StartWith<TSource>(default(IQueryable<TSource>), default(TSource[]))),
  1913. #else
  1914. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1915. #endif
  1916. source.Expression,
  1917. Expression.Constant(values, typeof(TSource[]))
  1918. )
  1919. );
  1920. }
  1921. #pragma warning disable 1591
  1922. [EditorBrowsable(EditorBrowsableState.Never)]
  1923. public static IEnumerable<TSource> StartWith<TSource>(IEnumerable<TSource> source, params TSource[] values)
  1924. {
  1925. return EnumerableEx.StartWith(source, values);
  1926. }
  1927. #pragma warning restore 1591
  1928. /// <summary>
  1929. /// Generates a sequence of accumulated values by scanning the source sequence and applying an accumulator function.
  1930. /// </summary>
  1931. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1932. /// <typeparam name="TAccumulate">Accumulation type.</typeparam>
  1933. /// <param name="source">Source sequence.</param>
  1934. /// <param name="seed">Accumulator seed value.</param>
  1935. /// <param name="accumulator">Accumulation function to apply to the current accumulation value and each element of the sequence.</param>
  1936. /// <returns>Sequence with all intermediate accumulation values resulting from scanning the sequence.</returns>
  1937. public static IQueryable<TAccumulate> Scan<TSource, TAccumulate>(this IQueryable<TSource> source, TAccumulate seed, Expression<Func<TAccumulate, TSource, TAccumulate>> accumulator)
  1938. {
  1939. if (source == null)
  1940. throw new ArgumentNullException("source");
  1941. if (accumulator == null)
  1942. throw new ArgumentNullException("accumulator");
  1943. return source.Provider.CreateQuery<TAccumulate>(
  1944. Expression.Call(
  1945. null,
  1946. #if CRIPPLED_REFLECTION
  1947. InfoOf(() => QueryableEx.Scan<TSource, TAccumulate>(default(IQueryable<TSource>), default(TAccumulate), default(Expression<Func<TAccumulate, TSource, TAccumulate>>))),
  1948. #else
  1949. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource), typeof(TAccumulate)),
  1950. #endif
  1951. source.Expression,
  1952. Expression.Constant(seed, typeof(TAccumulate)),
  1953. accumulator
  1954. )
  1955. );
  1956. }
  1957. #pragma warning disable 1591
  1958. [EditorBrowsable(EditorBrowsableState.Never)]
  1959. public static IEnumerable<TAccumulate> Scan<TSource, TAccumulate>(IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
  1960. {
  1961. return EnumerableEx.Scan(source, seed, accumulator);
  1962. }
  1963. #pragma warning restore 1591
  1964. /// <summary>
  1965. /// Generates a sequence of accumulated values by scanning the source sequence and applying an accumulator function.
  1966. /// </summary>
  1967. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  1968. /// <param name="source">Source sequence.</param>
  1969. /// <param name="accumulator">Accumulation function to apply to the current accumulation value and each element of the sequence.</param>
  1970. /// <returns>Sequence with all intermediate accumulation values resulting from scanning the sequence.</returns>
  1971. public static IQueryable<TSource> Scan<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, TSource, TSource>> accumulator)
  1972. {
  1973. if (source == null)
  1974. throw new ArgumentNullException("source");
  1975. if (accumulator == null)
  1976. throw new ArgumentNullException("accumulator");
  1977. return source.Provider.CreateQuery<TSource>(
  1978. Expression.Call(
  1979. null,
  1980. #if CRIPPLED_REFLECTION
  1981. InfoOf(() => QueryableEx.Scan<TSource>(default(IQueryable<TSource>), default(Expression<Func<TSource, TSource, TSource>>))),
  1982. #else
  1983. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  1984. #endif
  1985. source.Expression,
  1986. accumulator
  1987. )
  1988. );
  1989. }
  1990. #pragma warning disable 1591
  1991. [EditorBrowsable(EditorBrowsableState.Never)]
  1992. public static IEnumerable<TSource> Scan<TSource>(IEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator)
  1993. {
  1994. return EnumerableEx.Scan(source, accumulator);
  1995. }
  1996. #pragma warning restore 1591
  1997. /// <summary>
  1998. /// Returns a specified number of contiguous elements from the end of the sequence.
  1999. /// </summary>
  2000. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  2001. /// <param name="source">Source sequence.</param>
  2002. /// <param name="count">The number of elements to take from the end of the sequence.</param>
  2003. /// <returns>Sequence with the specified number of elements counting from the end of the source sequence.</returns>
  2004. public static IQueryable<TSource> TakeLast<TSource>(this IQueryable<TSource> source, int count)
  2005. {
  2006. if (source == null)
  2007. throw new ArgumentNullException("source");
  2008. return source.Provider.CreateQuery<TSource>(
  2009. Expression.Call(
  2010. null,
  2011. #if CRIPPLED_REFLECTION
  2012. InfoOf(() => QueryableEx.TakeLast<TSource>(default(IQueryable<TSource>), default(int))),
  2013. #else
  2014. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  2015. #endif
  2016. source.Expression,
  2017. Expression.Constant(count, typeof(int))
  2018. )
  2019. );
  2020. }
  2021. #pragma warning disable 1591
  2022. [EditorBrowsable(EditorBrowsableState.Never)]
  2023. public static IEnumerable<TSource> TakeLast<TSource>(IEnumerable<TSource> source, int count)
  2024. {
  2025. return EnumerableEx.TakeLast(source, count);
  2026. }
  2027. #pragma warning restore 1591
  2028. /// <summary>
  2029. /// Bypasses a specified number of contiguous elements from the end of the sequence and returns the remaining elements.
  2030. /// </summary>
  2031. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  2032. /// <param name="source">Source sequence.</param>
  2033. /// <param name="count">The number of elements to skip from the end of the sequence before returning the remaining elements.</param>
  2034. /// <returns>Sequence bypassing the specified number of elements counting from the end of the source sequence.</returns>
  2035. public static IQueryable<TSource> SkipLast<TSource>(this IQueryable<TSource> source, int count)
  2036. {
  2037. if (source == null)
  2038. throw new ArgumentNullException("source");
  2039. return source.Provider.CreateQuery<TSource>(
  2040. Expression.Call(
  2041. null,
  2042. #if CRIPPLED_REFLECTION
  2043. InfoOf(() => QueryableEx.SkipLast<TSource>(default(IQueryable<TSource>), default(int))),
  2044. #else
  2045. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  2046. #endif
  2047. source.Expression,
  2048. Expression.Constant(count, typeof(int))
  2049. )
  2050. );
  2051. }
  2052. #pragma warning disable 1591
  2053. [EditorBrowsable(EditorBrowsableState.Never)]
  2054. public static IEnumerable<TSource> SkipLast<TSource>(IEnumerable<TSource> source, int count)
  2055. {
  2056. return EnumerableEx.SkipLast(source, count);
  2057. }
  2058. #pragma warning restore 1591
  2059. /// <summary>
  2060. /// Repeats and concatenates the source sequence infinitely.
  2061. /// </summary>
  2062. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  2063. /// <param name="source">Source sequence.</param>
  2064. /// <returns>Sequence obtained by concatenating the source sequence to itself infinitely.</returns>
  2065. public static IQueryable<TSource> Repeat<TSource>(this IQueryable<TSource> source)
  2066. {
  2067. if (source == null)
  2068. throw new ArgumentNullException("source");
  2069. return source.Provider.CreateQuery<TSource>(
  2070. Expression.Call(
  2071. null,
  2072. #if CRIPPLED_REFLECTION
  2073. InfoOf(() => QueryableEx.Repeat<TSource>(default(IQueryable<TSource>))),
  2074. #else
  2075. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  2076. #endif
  2077. source.Expression
  2078. )
  2079. );
  2080. }
  2081. #pragma warning disable 1591
  2082. [EditorBrowsable(EditorBrowsableState.Never)]
  2083. public static IEnumerable<TSource> Repeat<TSource>(IEnumerable<TSource> source)
  2084. {
  2085. return EnumerableEx.Repeat(source);
  2086. }
  2087. #pragma warning restore 1591
  2088. /// <summary>
  2089. /// Repeats and concatenates the source sequence the given number of times.
  2090. /// </summary>
  2091. /// <typeparam name="TSource">Source sequence element type.</typeparam>
  2092. /// <param name="source">Source sequence.</param>
  2093. /// <param name="count">Number of times to repeat the source sequence.</param>
  2094. /// <returns>Sequence obtained by concatenating the source sequence to itself the specified number of times.</returns>
  2095. public static IQueryable<TSource> Repeat<TSource>(this IQueryable<TSource> source, int count)
  2096. {
  2097. if (source == null)
  2098. throw new ArgumentNullException("source");
  2099. return source.Provider.CreateQuery<TSource>(
  2100. Expression.Call(
  2101. null,
  2102. #if CRIPPLED_REFLECTION
  2103. InfoOf(() => QueryableEx.Repeat<TSource>(default(IQueryable<TSource>), default(int))),
  2104. #else
  2105. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TSource)),
  2106. #endif
  2107. source.Expression,
  2108. Expression.Constant(count, typeof(int))
  2109. )
  2110. );
  2111. }
  2112. #pragma warning disable 1591
  2113. [EditorBrowsable(EditorBrowsableState.Never)]
  2114. public static IEnumerable<TSource> Repeat<TSource>(IEnumerable<TSource> source, int count)
  2115. {
  2116. return EnumerableEx.Repeat(source, count);
  2117. }
  2118. #pragma warning restore 1591
  2119. /// <summary>
  2120. /// Returns a sequence with no elements.
  2121. /// </summary>
  2122. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  2123. /// <param name="provider">Query provider.</param>
  2124. /// <returns>Sequence with no elements.</returns>
  2125. public static IQueryable<TResult> Empty<TResult>(this IQueryProvider provider)
  2126. {
  2127. if (provider == null)
  2128. throw new ArgumentNullException("provider");
  2129. return provider.CreateQuery<TResult>(
  2130. Expression.Call(
  2131. null,
  2132. #if CRIPPLED_REFLECTION
  2133. InfoOf(() => QueryableEx.Empty<TResult>(default(IQueryProvider))),
  2134. #else
  2135. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  2136. #endif
  2137. Expression.Constant(provider, typeof(IQueryProvider))
  2138. )
  2139. );
  2140. }
  2141. #pragma warning disable 1591
  2142. [EditorBrowsable(EditorBrowsableState.Never)]
  2143. public static /*!*/IQueryable<TResult> Empty<TResult>()
  2144. {
  2145. return Enumerable.Empty<TResult>().AsQueryable();
  2146. }
  2147. #pragma warning restore 1591
  2148. /// <summary>
  2149. /// Generates a sequence of integral numbers within a specified range.
  2150. /// </summary>
  2151. /// <param name="provider">Query provider.</param>
  2152. /// <param name="start">The value of the first integer in the sequence.</param>
  2153. /// <param name="count">The number of sequential integers to generate.</param>
  2154. /// <returns>Sequence that contains a range of sequential integral numbers.</returns>
  2155. public static IQueryable<int> Range(this IQueryProvider provider, int start, int count)
  2156. {
  2157. if (provider == null)
  2158. throw new ArgumentNullException("provider");
  2159. return provider.CreateQuery<int>(
  2160. Expression.Call(
  2161. null,
  2162. #if CRIPPLED_REFLECTION
  2163. InfoOf(() => QueryableEx.Range(default(IQueryProvider), default(int), default(int))),
  2164. #else
  2165. (MethodInfo)MethodInfo.GetCurrentMethod(),
  2166. #endif
  2167. Expression.Constant(provider, typeof(IQueryProvider)),
  2168. Expression.Constant(start, typeof(int)),
  2169. Expression.Constant(count, typeof(int))
  2170. )
  2171. );
  2172. }
  2173. #pragma warning disable 1591
  2174. [EditorBrowsable(EditorBrowsableState.Never)]
  2175. public static /*!*/IQueryable<int> Range(int start, int count)
  2176. {
  2177. return Enumerable.Range(start, count).AsQueryable();
  2178. }
  2179. #pragma warning restore 1591
  2180. /// <summary>
  2181. /// Generates a sequence that contains one repeated value.
  2182. /// </summary>
  2183. /// <typeparam name="TResult">Result sequence element type.</typeparam>
  2184. /// <param name="provider">Query provider.</param>
  2185. /// <param name="element">The value to be repeated.</param>
  2186. /// <param name="count">The number of times to repeat the value in the generated sequence.</param>
  2187. /// <returns>Sequence that contains a repeated value.</returns>
  2188. public static IQueryable<TResult> Repeat<TResult>(this IQueryProvider provider, TResult element, int count)
  2189. {
  2190. if (provider == null)
  2191. throw new ArgumentNullException("provider");
  2192. return provider.CreateQuery<TResult>(
  2193. Expression.Call(
  2194. null,
  2195. #if CRIPPLED_REFLECTION
  2196. InfoOf(() => QueryableEx.Repeat<TResult>(default(IQueryProvider), default(TResult), default(int))),
  2197. #else
  2198. ((MethodInfo)MethodInfo.GetCurrentMethod()).MakeGenericMethod(typeof(TResult)),
  2199. #endif
  2200. Expression.Constant(provider, typeof(IQueryProvider)),
  2201. Expression.Constant(element, typeof(TResult)),
  2202. Expression.Constant(count, typeof(int))
  2203. )
  2204. );
  2205. }
  2206. #pragma warning disable 1591
  2207. [EditorBrowsable(EditorBrowsableState.Never)]
  2208. public static /*!*/IQueryable<TResult> Repeat<TResult>(TResult element, int count)
  2209. {
  2210. return EnumerableEx.Repeat<TResult>(element, count).AsQueryable();
  2211. }
  2212. #pragma warning restore 1591
  2213. /// <summary>
  2214. /// Gets the local Queryable provider.
  2215. /// </summary>
  2216. public static IQueryProvider Provider
  2217. {
  2218. get
  2219. {
  2220. return new QueryProviderShim();
  2221. }
  2222. }
  2223. class QueryProviderShim : IQueryProvider
  2224. {
  2225. public IQueryable<TElement> CreateQuery<TElement>(Expression expression)
  2226. {
  2227. var provider = new TElement[0].AsQueryable().Provider;
  2228. var res = Redir(expression);
  2229. return provider.CreateQuery<TElement>(res);
  2230. }
  2231. public IQueryable CreateQuery(Expression expression)
  2232. {
  2233. return CreateQuery<object>(expression);
  2234. }
  2235. public TResult Execute<TResult>(Expression expression)
  2236. {
  2237. var provider = new TResult[0].AsQueryable().Provider;
  2238. var res = Redir(expression);
  2239. return provider.Execute<TResult>(res);
  2240. }
  2241. public object Execute(Expression expression)
  2242. {
  2243. return Execute<object>(expression);
  2244. }
  2245. private static Expression Redir(Expression expression)
  2246. {
  2247. var mce = expression as MethodCallExpression;
  2248. if (mce != null && mce.Method.DeclaringType == typeof(QueryableEx))
  2249. {
  2250. if (mce.Arguments.Count >= 1 && typeof(IQueryProvider).IsAssignableFrom(mce.Arguments[0].Type))
  2251. {
  2252. var ce = mce.Arguments[0] as ConstantExpression;
  2253. if (ce != null)
  2254. {
  2255. if (ce.Value is QueryProviderShim)
  2256. {
  2257. var targetType = typeof(QueryableEx);
  2258. var method = mce.Method;
  2259. var methods = GetMethods(targetType);
  2260. var arguments = mce.Arguments.Skip(1).ToList();
  2261. //
  2262. // From all the operators with the method's name, find the one that matches all arguments.
  2263. //
  2264. var typeArgs = method.IsGenericMethod ? method.GetGenericArguments() : null;
  2265. var targetMethod = methods[method.Name].FirstOrDefault(candidateMethod => ArgsMatch(candidateMethod, arguments, typeArgs));
  2266. if (targetMethod == null)
  2267. throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "There is no method '{0}' on type '{1}' that matches the specified arguments", method.Name, targetType.Name));
  2268. //
  2269. // Restore generic arguments.
  2270. //
  2271. if (typeArgs != null)
  2272. targetMethod = targetMethod.MakeGenericMethod(typeArgs);
  2273. //
  2274. // Finally, we need to deal with mismatches on Expression<Func<...>> versus Func<...>.
  2275. //
  2276. var parameters = targetMethod.GetParameters();
  2277. for (int i = 0, n = parameters.Length; i < n; i++)
  2278. {
  2279. arguments[i] = Unquote(arguments[i]);
  2280. }
  2281. //
  2282. // Emit a new call to the discovered target method.
  2283. //
  2284. return Expression.Call(null, targetMethod, arguments);
  2285. }
  2286. }
  2287. }
  2288. }
  2289. return expression;
  2290. }
  2291. private static ILookup<string, MethodInfo> GetMethods(Type type)
  2292. {
  2293. return type.GetMethods(BindingFlags.Static | BindingFlags.Public).ToLookup(m => m.Name);
  2294. }
  2295. private static bool ArgsMatch(MethodInfo method, IList<Expression> arguments, Type[] typeArgs)
  2296. {
  2297. //
  2298. // Number of parameters should match. Notice we've sanitized IQueryProvider "this"
  2299. // parameters first (see Redir).
  2300. //
  2301. var parameters = method.GetParameters();
  2302. if (parameters.Length != arguments.Count)
  2303. return false;
  2304. //
  2305. // Genericity should match too.
  2306. //
  2307. if (!method.IsGenericMethod && typeArgs != null && typeArgs.Length > 0)
  2308. return false;
  2309. //
  2310. // Reconstruct the generic method if needed.
  2311. //
  2312. if (method.IsGenericMethodDefinition)
  2313. {
  2314. if (typeArgs == null)
  2315. return false;
  2316. if (method.GetGenericArguments().Length != typeArgs.Length)
  2317. return false;
  2318. var result = method.MakeGenericMethod(typeArgs);
  2319. parameters = result.GetParameters();
  2320. }
  2321. //
  2322. // Check compatibility for the parameter types.
  2323. //
  2324. for (int i = 0, n = arguments.Count; i < n; i++)
  2325. {
  2326. var parameterType = parameters[i].ParameterType;
  2327. var argument = arguments[i];
  2328. //
  2329. // For operators that take a function (like Where, Select), we'll be faced
  2330. // with a quoted argument and a discrepancy between Expression<Func<...>>
  2331. // and the underlying Func<...>.
  2332. //
  2333. if (!parameterType.IsAssignableFrom(argument.Type))
  2334. {
  2335. argument = Unquote(argument);
  2336. if (!parameterType.IsAssignableFrom(argument.Type))
  2337. return false;
  2338. }
  2339. }
  2340. return true;
  2341. }
  2342. private static Expression Unquote(Expression expression)
  2343. {
  2344. //
  2345. // Get rid of all outer quotes around an expression.
  2346. //
  2347. while (expression.NodeType == ExpressionType.Quote)
  2348. expression = ((UnaryExpression)expression).Operand;
  2349. return expression;
  2350. }
  2351. }
  2352. internal static Expression GetSourceExpression<TSource>(IEnumerable<TSource> source)
  2353. {
  2354. var q = source as IQueryable<TSource>;
  2355. if (q != null)
  2356. return q.Expression;
  2357. return Expression.Constant(source, typeof(IEnumerable<TSource>));
  2358. }
  2359. internal static Expression GetSourceExpression<TSource>(IEnumerable<TSource>[] sources)
  2360. {
  2361. return Expression.NewArrayInit(
  2362. typeof(IEnumerable<TSource>),
  2363. sources.Select(source => GetSourceExpression(source))
  2364. );
  2365. }
  2366. internal static MethodInfo InfoOf<R>(Expression<Func<R>> f)
  2367. {
  2368. return ((MethodCallExpression)f.Body).Method;
  2369. }
  2370. }
  2371. }