Average.Generated.cs 93 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. namespace System.Linq
  8. {
  9. public static partial class AsyncEnumerable
  10. {
  11. /// <summary>
  12. /// Computes the average of an async-enumerable sequence of <see cref="int" /> values.
  13. /// </summary>
  14. /// <param name="source">A sequence of <see cref="int" /> values to calculate the average of.</param>
  15. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  16. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  17. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  18. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  19. public static ValueTask<double> AverageAsync(this IAsyncEnumerable<int> source, CancellationToken cancellationToken = default)
  20. {
  21. if (source == null)
  22. throw Error.ArgumentNull(nameof(source));
  23. return Core(source, cancellationToken);
  24. static async ValueTask<double> Core(IAsyncEnumerable<int> source, CancellationToken cancellationToken)
  25. {
  26. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  27. {
  28. if (!await e.MoveNextAsync())
  29. {
  30. throw Error.NoElements();
  31. }
  32. long sum = e.Current;
  33. long count = 1;
  34. checked
  35. {
  36. while (await e.MoveNextAsync())
  37. {
  38. sum += e.Current;
  39. ++count;
  40. }
  41. }
  42. return (double)sum / count;
  43. }
  44. }
  45. }
  46. /// <summary>
  47. /// Computes the average of an async-enumerable sequence of <see cref="int" /> values that are obtained by invoking a transform function on each element of the input sequence.
  48. /// </summary>
  49. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  50. /// <param name="source">A sequence of values to calculate the average of.</param>
  51. /// <param name="selector">A transform function to apply to each element.</param>
  52. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  53. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  54. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  55. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  56. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  57. public static ValueTask<double> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int> selector, CancellationToken cancellationToken = default)
  58. {
  59. if (source == null)
  60. throw Error.ArgumentNull(nameof(source));
  61. if (selector == null)
  62. throw Error.ArgumentNull(nameof(selector));
  63. return Core(source, selector, cancellationToken);
  64. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, int> selector, CancellationToken cancellationToken)
  65. {
  66. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  67. {
  68. if (!await e.MoveNextAsync())
  69. {
  70. throw Error.NoElements();
  71. }
  72. long sum = selector(e.Current);
  73. long count = 1;
  74. checked
  75. {
  76. while (await e.MoveNextAsync())
  77. {
  78. sum += selector(e.Current);
  79. ++count;
  80. }
  81. }
  82. return (double)sum / count;
  83. }
  84. }
  85. }
  86. /// <summary>
  87. /// Computes the average of an async-enumerable sequence of <see cref="int"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  88. /// </summary>
  89. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  90. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  91. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  92. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  93. /// <returns>A ValueTask containing the average of the sequence of values.</returns>
  94. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  95. /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
  96. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  97. [GenerateAsyncOverload]
  98. private static ValueTask<double> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<int>> selector, CancellationToken cancellationToken = default)
  99. {
  100. if (source == null)
  101. throw Error.ArgumentNull(nameof(source));
  102. if (selector == null)
  103. throw Error.ArgumentNull(nameof(selector));
  104. return Core(source, selector, cancellationToken);
  105. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<int>> selector, CancellationToken cancellationToken)
  106. {
  107. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  108. {
  109. if (!await e.MoveNextAsync())
  110. {
  111. throw Error.NoElements();
  112. }
  113. long sum = await selector(e.Current).ConfigureAwait(false);
  114. long count = 1;
  115. checked
  116. {
  117. while (await e.MoveNextAsync())
  118. {
  119. sum += await selector(e.Current).ConfigureAwait(false);
  120. ++count;
  121. }
  122. }
  123. return (double)sum / count;
  124. }
  125. }
  126. }
  127. #if !NO_DEEP_CANCELLATION
  128. [GenerateAsyncOverload]
  129. private static ValueTask<double> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<int>> selector, CancellationToken cancellationToken = default)
  130. {
  131. if (source == null)
  132. throw Error.ArgumentNull(nameof(source));
  133. if (selector == null)
  134. throw Error.ArgumentNull(nameof(selector));
  135. return Core(source, selector, cancellationToken);
  136. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<int>> selector, CancellationToken cancellationToken)
  137. {
  138. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  139. {
  140. if (!await e.MoveNextAsync())
  141. {
  142. throw Error.NoElements();
  143. }
  144. long sum = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  145. long count = 1;
  146. checked
  147. {
  148. while (await e.MoveNextAsync())
  149. {
  150. sum += await selector(e.Current, cancellationToken).ConfigureAwait(false);
  151. ++count;
  152. }
  153. }
  154. return (double)sum / count;
  155. }
  156. }
  157. }
  158. #endif
  159. /// <summary>
  160. /// Computes the average of an async-enumerable sequence of <see cref="long" /> values.
  161. /// </summary>
  162. /// <param name="source">A sequence of <see cref="long" /> values to calculate the average of.</param>
  163. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  164. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  165. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  166. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  167. public static ValueTask<double> AverageAsync(this IAsyncEnumerable<long> source, CancellationToken cancellationToken = default)
  168. {
  169. if (source == null)
  170. throw Error.ArgumentNull(nameof(source));
  171. return Core(source, cancellationToken);
  172. static async ValueTask<double> Core(IAsyncEnumerable<long> source, CancellationToken cancellationToken)
  173. {
  174. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  175. {
  176. if (!await e.MoveNextAsync())
  177. {
  178. throw Error.NoElements();
  179. }
  180. long sum = e.Current;
  181. long count = 1;
  182. checked
  183. {
  184. while (await e.MoveNextAsync())
  185. {
  186. sum += e.Current;
  187. ++count;
  188. }
  189. }
  190. return (double)sum / count;
  191. }
  192. }
  193. }
  194. /// <summary>
  195. /// Computes the average of an async-enumerable sequence of <see cref="long" /> values that are obtained by invoking a transform function on each element of the input sequence.
  196. /// </summary>
  197. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  198. /// <param name="source">A sequence of values to calculate the average of.</param>
  199. /// <param name="selector">A transform function to apply to each element.</param>
  200. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  201. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  202. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  203. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  204. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  205. public static ValueTask<double> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, long> selector, CancellationToken cancellationToken = default)
  206. {
  207. if (source == null)
  208. throw Error.ArgumentNull(nameof(source));
  209. if (selector == null)
  210. throw Error.ArgumentNull(nameof(selector));
  211. return Core(source, selector, cancellationToken);
  212. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, long> selector, CancellationToken cancellationToken)
  213. {
  214. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  215. {
  216. if (!await e.MoveNextAsync())
  217. {
  218. throw Error.NoElements();
  219. }
  220. long sum = selector(e.Current);
  221. long count = 1;
  222. checked
  223. {
  224. while (await e.MoveNextAsync())
  225. {
  226. sum += selector(e.Current);
  227. ++count;
  228. }
  229. }
  230. return (double)sum / count;
  231. }
  232. }
  233. }
  234. /// <summary>
  235. /// Computes the average of an async-enumerable sequence of <see cref="long"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  236. /// </summary>
  237. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  238. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  239. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  240. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  241. /// <returns>A ValueTask containing the average of the sequence of values.</returns>
  242. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  243. /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
  244. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  245. [GenerateAsyncOverload]
  246. private static ValueTask<double> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<long>> selector, CancellationToken cancellationToken = default)
  247. {
  248. if (source == null)
  249. throw Error.ArgumentNull(nameof(source));
  250. if (selector == null)
  251. throw Error.ArgumentNull(nameof(selector));
  252. return Core(source, selector, cancellationToken);
  253. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<long>> selector, CancellationToken cancellationToken)
  254. {
  255. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  256. {
  257. if (!await e.MoveNextAsync())
  258. {
  259. throw Error.NoElements();
  260. }
  261. long sum = await selector(e.Current).ConfigureAwait(false);
  262. long count = 1;
  263. checked
  264. {
  265. while (await e.MoveNextAsync())
  266. {
  267. sum += await selector(e.Current).ConfigureAwait(false);
  268. ++count;
  269. }
  270. }
  271. return (double)sum / count;
  272. }
  273. }
  274. }
  275. #if !NO_DEEP_CANCELLATION
  276. [GenerateAsyncOverload]
  277. private static ValueTask<double> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<long>> selector, CancellationToken cancellationToken = default)
  278. {
  279. if (source == null)
  280. throw Error.ArgumentNull(nameof(source));
  281. if (selector == null)
  282. throw Error.ArgumentNull(nameof(selector));
  283. return Core(source, selector, cancellationToken);
  284. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<long>> selector, CancellationToken cancellationToken)
  285. {
  286. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  287. {
  288. if (!await e.MoveNextAsync())
  289. {
  290. throw Error.NoElements();
  291. }
  292. long sum = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  293. long count = 1;
  294. checked
  295. {
  296. while (await e.MoveNextAsync())
  297. {
  298. sum += await selector(e.Current, cancellationToken).ConfigureAwait(false);
  299. ++count;
  300. }
  301. }
  302. return (double)sum / count;
  303. }
  304. }
  305. }
  306. #endif
  307. /// <summary>
  308. /// Computes the average of an async-enumerable sequence of <see cref="float" /> values.
  309. /// </summary>
  310. /// <param name="source">A sequence of <see cref="float" /> values to calculate the average of.</param>
  311. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  312. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  313. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  314. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  315. public static ValueTask<float> AverageAsync(this IAsyncEnumerable<float> source, CancellationToken cancellationToken = default)
  316. {
  317. if (source == null)
  318. throw Error.ArgumentNull(nameof(source));
  319. return Core(source, cancellationToken);
  320. static async ValueTask<float> Core(IAsyncEnumerable<float> source, CancellationToken cancellationToken)
  321. {
  322. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  323. {
  324. if (!await e.MoveNextAsync())
  325. {
  326. throw Error.NoElements();
  327. }
  328. double sum = e.Current;
  329. long count = 1;
  330. checked
  331. {
  332. while (await e.MoveNextAsync())
  333. {
  334. sum += e.Current;
  335. ++count;
  336. }
  337. }
  338. return (float)(sum / count);
  339. }
  340. }
  341. }
  342. /// <summary>
  343. /// Computes the average of an async-enumerable sequence of <see cref="float" /> values that are obtained by invoking a transform function on each element of the input sequence.
  344. /// </summary>
  345. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  346. /// <param name="source">A sequence of values to calculate the average of.</param>
  347. /// <param name="selector">A transform function to apply to each element.</param>
  348. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  349. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  350. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  351. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  352. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  353. public static ValueTask<float> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, float> selector, CancellationToken cancellationToken = default)
  354. {
  355. if (source == null)
  356. throw Error.ArgumentNull(nameof(source));
  357. if (selector == null)
  358. throw Error.ArgumentNull(nameof(selector));
  359. return Core(source, selector, cancellationToken);
  360. static async ValueTask<float> Core(IAsyncEnumerable<TSource> source, Func<TSource, float> selector, CancellationToken cancellationToken)
  361. {
  362. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  363. {
  364. if (!await e.MoveNextAsync())
  365. {
  366. throw Error.NoElements();
  367. }
  368. double sum = selector(e.Current);
  369. long count = 1;
  370. checked
  371. {
  372. while (await e.MoveNextAsync())
  373. {
  374. sum += selector(e.Current);
  375. ++count;
  376. }
  377. }
  378. return (float)(sum / count);
  379. }
  380. }
  381. }
  382. /// <summary>
  383. /// Computes the average of an async-enumerable sequence of <see cref="float"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  384. /// </summary>
  385. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  386. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  387. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  388. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  389. /// <returns>A ValueTask containing the average of the sequence of values.</returns>
  390. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  391. /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
  392. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  393. [GenerateAsyncOverload]
  394. private static ValueTask<float> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<float>> selector, CancellationToken cancellationToken = default)
  395. {
  396. if (source == null)
  397. throw Error.ArgumentNull(nameof(source));
  398. if (selector == null)
  399. throw Error.ArgumentNull(nameof(selector));
  400. return Core(source, selector, cancellationToken);
  401. static async ValueTask<float> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<float>> selector, CancellationToken cancellationToken)
  402. {
  403. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  404. {
  405. if (!await e.MoveNextAsync())
  406. {
  407. throw Error.NoElements();
  408. }
  409. double sum = await selector(e.Current).ConfigureAwait(false);
  410. long count = 1;
  411. checked
  412. {
  413. while (await e.MoveNextAsync())
  414. {
  415. sum += await selector(e.Current).ConfigureAwait(false);
  416. ++count;
  417. }
  418. }
  419. return (float)(sum / count);
  420. }
  421. }
  422. }
  423. #if !NO_DEEP_CANCELLATION
  424. [GenerateAsyncOverload]
  425. private static ValueTask<float> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<float>> selector, CancellationToken cancellationToken = default)
  426. {
  427. if (source == null)
  428. throw Error.ArgumentNull(nameof(source));
  429. if (selector == null)
  430. throw Error.ArgumentNull(nameof(selector));
  431. return Core(source, selector, cancellationToken);
  432. static async ValueTask<float> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<float>> selector, CancellationToken cancellationToken)
  433. {
  434. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  435. {
  436. if (!await e.MoveNextAsync())
  437. {
  438. throw Error.NoElements();
  439. }
  440. double sum = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  441. long count = 1;
  442. checked
  443. {
  444. while (await e.MoveNextAsync())
  445. {
  446. sum += await selector(e.Current, cancellationToken).ConfigureAwait(false);
  447. ++count;
  448. }
  449. }
  450. return (float)(sum / count);
  451. }
  452. }
  453. }
  454. #endif
  455. /// <summary>
  456. /// Computes the average of an async-enumerable sequence of <see cref="double" /> values.
  457. /// </summary>
  458. /// <param name="source">A sequence of <see cref="double" /> values to calculate the average of.</param>
  459. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  460. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  461. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  462. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  463. public static ValueTask<double> AverageAsync(this IAsyncEnumerable<double> source, CancellationToken cancellationToken = default)
  464. {
  465. if (source == null)
  466. throw Error.ArgumentNull(nameof(source));
  467. return Core(source, cancellationToken);
  468. static async ValueTask<double> Core(IAsyncEnumerable<double> source, CancellationToken cancellationToken)
  469. {
  470. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  471. {
  472. if (!await e.MoveNextAsync())
  473. {
  474. throw Error.NoElements();
  475. }
  476. double sum = e.Current;
  477. long count = 1;
  478. checked
  479. {
  480. while (await e.MoveNextAsync())
  481. {
  482. sum += e.Current;
  483. ++count;
  484. }
  485. }
  486. return sum / count;
  487. }
  488. }
  489. }
  490. /// <summary>
  491. /// Computes the average of an async-enumerable sequence of <see cref="double" /> values that are obtained by invoking a transform function on each element of the input sequence.
  492. /// </summary>
  493. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  494. /// <param name="source">A sequence of values to calculate the average of.</param>
  495. /// <param name="selector">A transform function to apply to each element.</param>
  496. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  497. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  498. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  499. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  500. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  501. public static ValueTask<double> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, double> selector, CancellationToken cancellationToken = default)
  502. {
  503. if (source == null)
  504. throw Error.ArgumentNull(nameof(source));
  505. if (selector == null)
  506. throw Error.ArgumentNull(nameof(selector));
  507. return Core(source, selector, cancellationToken);
  508. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, double> selector, CancellationToken cancellationToken)
  509. {
  510. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  511. {
  512. if (!await e.MoveNextAsync())
  513. {
  514. throw Error.NoElements();
  515. }
  516. double sum = selector(e.Current);
  517. long count = 1;
  518. checked
  519. {
  520. while (await e.MoveNextAsync())
  521. {
  522. sum += selector(e.Current);
  523. ++count;
  524. }
  525. }
  526. return sum / count;
  527. }
  528. }
  529. }
  530. /// <summary>
  531. /// Computes the average of an async-enumerable sequence of <see cref="double"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  532. /// </summary>
  533. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  534. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  535. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  536. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  537. /// <returns>A ValueTask containing the average of the sequence of values.</returns>
  538. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  539. /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
  540. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  541. [GenerateAsyncOverload]
  542. private static ValueTask<double> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<double>> selector, CancellationToken cancellationToken = default)
  543. {
  544. if (source == null)
  545. throw Error.ArgumentNull(nameof(source));
  546. if (selector == null)
  547. throw Error.ArgumentNull(nameof(selector));
  548. return Core(source, selector, cancellationToken);
  549. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<double>> selector, CancellationToken cancellationToken)
  550. {
  551. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  552. {
  553. if (!await e.MoveNextAsync())
  554. {
  555. throw Error.NoElements();
  556. }
  557. double sum = await selector(e.Current).ConfigureAwait(false);
  558. long count = 1;
  559. checked
  560. {
  561. while (await e.MoveNextAsync())
  562. {
  563. sum += await selector(e.Current).ConfigureAwait(false);
  564. ++count;
  565. }
  566. }
  567. return sum / count;
  568. }
  569. }
  570. }
  571. #if !NO_DEEP_CANCELLATION
  572. [GenerateAsyncOverload]
  573. private static ValueTask<double> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<double>> selector, CancellationToken cancellationToken = default)
  574. {
  575. if (source == null)
  576. throw Error.ArgumentNull(nameof(source));
  577. if (selector == null)
  578. throw Error.ArgumentNull(nameof(selector));
  579. return Core(source, selector, cancellationToken);
  580. static async ValueTask<double> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<double>> selector, CancellationToken cancellationToken)
  581. {
  582. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  583. {
  584. if (!await e.MoveNextAsync())
  585. {
  586. throw Error.NoElements();
  587. }
  588. double sum = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  589. long count = 1;
  590. checked
  591. {
  592. while (await e.MoveNextAsync())
  593. {
  594. sum += await selector(e.Current, cancellationToken).ConfigureAwait(false);
  595. ++count;
  596. }
  597. }
  598. return sum / count;
  599. }
  600. }
  601. }
  602. #endif
  603. /// <summary>
  604. /// Computes the average of an async-enumerable sequence of <see cref="decimal" /> values.
  605. /// </summary>
  606. /// <param name="source">A sequence of <see cref="decimal" /> values to calculate the average of.</param>
  607. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  608. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  609. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  610. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  611. public static ValueTask<decimal> AverageAsync(this IAsyncEnumerable<decimal> source, CancellationToken cancellationToken = default)
  612. {
  613. if (source == null)
  614. throw Error.ArgumentNull(nameof(source));
  615. return Core(source, cancellationToken);
  616. static async ValueTask<decimal> Core(IAsyncEnumerable<decimal> source, CancellationToken cancellationToken)
  617. {
  618. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  619. {
  620. if (!await e.MoveNextAsync())
  621. {
  622. throw Error.NoElements();
  623. }
  624. decimal sum = e.Current;
  625. long count = 1;
  626. checked
  627. {
  628. while (await e.MoveNextAsync())
  629. {
  630. sum += e.Current;
  631. ++count;
  632. }
  633. }
  634. return sum / count;
  635. }
  636. }
  637. }
  638. /// <summary>
  639. /// Computes the average of an async-enumerable sequence of <see cref="decimal" /> values that are obtained by invoking a transform function on each element of the input sequence.
  640. /// </summary>
  641. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  642. /// <param name="source">A sequence of values to calculate the average of.</param>
  643. /// <param name="selector">A transform function to apply to each element.</param>
  644. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  645. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  646. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  647. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  648. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  649. public static ValueTask<decimal> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, decimal> selector, CancellationToken cancellationToken = default)
  650. {
  651. if (source == null)
  652. throw Error.ArgumentNull(nameof(source));
  653. if (selector == null)
  654. throw Error.ArgumentNull(nameof(selector));
  655. return Core(source, selector, cancellationToken);
  656. static async ValueTask<decimal> Core(IAsyncEnumerable<TSource> source, Func<TSource, decimal> selector, CancellationToken cancellationToken)
  657. {
  658. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  659. {
  660. if (!await e.MoveNextAsync())
  661. {
  662. throw Error.NoElements();
  663. }
  664. decimal sum = selector(e.Current);
  665. long count = 1;
  666. checked
  667. {
  668. while (await e.MoveNextAsync())
  669. {
  670. sum += selector(e.Current);
  671. ++count;
  672. }
  673. }
  674. return sum / count;
  675. }
  676. }
  677. }
  678. /// <summary>
  679. /// Computes the average of an async-enumerable sequence of <see cref="decimal"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  680. /// </summary>
  681. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  682. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  683. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  684. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  685. /// <returns>A ValueTask containing the average of the sequence of values.</returns>
  686. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  687. /// <exception cref="InvalidOperationException">The source sequence is empty.</exception>
  688. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  689. [GenerateAsyncOverload]
  690. private static ValueTask<decimal> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<decimal>> selector, CancellationToken cancellationToken = default)
  691. {
  692. if (source == null)
  693. throw Error.ArgumentNull(nameof(source));
  694. if (selector == null)
  695. throw Error.ArgumentNull(nameof(selector));
  696. return Core(source, selector, cancellationToken);
  697. static async ValueTask<decimal> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<decimal>> selector, CancellationToken cancellationToken)
  698. {
  699. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  700. {
  701. if (!await e.MoveNextAsync())
  702. {
  703. throw Error.NoElements();
  704. }
  705. decimal sum = await selector(e.Current).ConfigureAwait(false);
  706. long count = 1;
  707. checked
  708. {
  709. while (await e.MoveNextAsync())
  710. {
  711. sum += await selector(e.Current).ConfigureAwait(false);
  712. ++count;
  713. }
  714. }
  715. return sum / count;
  716. }
  717. }
  718. }
  719. #if !NO_DEEP_CANCELLATION
  720. [GenerateAsyncOverload]
  721. private static ValueTask<decimal> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<decimal>> selector, CancellationToken cancellationToken = default)
  722. {
  723. if (source == null)
  724. throw Error.ArgumentNull(nameof(source));
  725. if (selector == null)
  726. throw Error.ArgumentNull(nameof(selector));
  727. return Core(source, selector, cancellationToken);
  728. static async ValueTask<decimal> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<decimal>> selector, CancellationToken cancellationToken)
  729. {
  730. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  731. {
  732. if (!await e.MoveNextAsync())
  733. {
  734. throw Error.NoElements();
  735. }
  736. decimal sum = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  737. long count = 1;
  738. checked
  739. {
  740. while (await e.MoveNextAsync())
  741. {
  742. sum += await selector(e.Current, cancellationToken).ConfigureAwait(false);
  743. ++count;
  744. }
  745. }
  746. return sum / count;
  747. }
  748. }
  749. }
  750. #endif
  751. /// <summary>
  752. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Int}" /> values.
  753. /// </summary>
  754. /// <param name="source">A sequence of <see cref="Nullable{Int}" /> values to calculate the average of.</param>
  755. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  756. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  757. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  758. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  759. public static ValueTask<double?> AverageAsync(this IAsyncEnumerable<int?> source, CancellationToken cancellationToken = default)
  760. {
  761. if (source == null)
  762. throw Error.ArgumentNull(nameof(source));
  763. return Core(source, cancellationToken);
  764. static async ValueTask<double?> Core(IAsyncEnumerable<int?> source, CancellationToken cancellationToken)
  765. {
  766. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  767. {
  768. while (await e.MoveNextAsync())
  769. {
  770. var v = e.Current;
  771. if (v.HasValue)
  772. {
  773. long sum = v.GetValueOrDefault();
  774. long count = 1;
  775. checked
  776. {
  777. while (await e.MoveNextAsync())
  778. {
  779. v = e.Current;
  780. if (v.HasValue)
  781. {
  782. sum += v.GetValueOrDefault();
  783. ++count;
  784. }
  785. }
  786. }
  787. return (double)sum / count;
  788. }
  789. }
  790. }
  791. return null;
  792. }
  793. }
  794. /// <summary>
  795. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Int}" /> values that are obtained by invoking a transform function on each element of the input sequence.
  796. /// </summary>
  797. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  798. /// <param name="source">A sequence of values to calculate the average of.</param>
  799. /// <param name="selector">A transform function to apply to each element.</param>
  800. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  801. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  802. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  803. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  804. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  805. public static ValueTask<double?> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int?> selector, CancellationToken cancellationToken = default)
  806. {
  807. if (source == null)
  808. throw Error.ArgumentNull(nameof(source));
  809. if (selector == null)
  810. throw Error.ArgumentNull(nameof(selector));
  811. return Core(source, selector, cancellationToken);
  812. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, int?> selector, CancellationToken cancellationToken)
  813. {
  814. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  815. {
  816. while (await e.MoveNextAsync())
  817. {
  818. var v = selector(e.Current);
  819. if (v.HasValue)
  820. {
  821. long sum = v.GetValueOrDefault();
  822. long count = 1;
  823. checked
  824. {
  825. while (await e.MoveNextAsync())
  826. {
  827. v = selector(e.Current);
  828. if (v.HasValue)
  829. {
  830. sum += v.GetValueOrDefault();
  831. ++count;
  832. }
  833. }
  834. }
  835. return (double)sum / count;
  836. }
  837. }
  838. }
  839. return null;
  840. }
  841. }
  842. /// <summary>
  843. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Int}"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  844. /// </summary>
  845. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  846. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  847. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  848. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  849. /// <returns>A ValueTask containing the average of the sequence of values, or <see langword="null"/> if the source sequence is empty.</returns>
  850. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  851. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  852. [GenerateAsyncOverload]
  853. private static ValueTask<double?> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<int?>> selector, CancellationToken cancellationToken = default)
  854. {
  855. if (source == null)
  856. throw Error.ArgumentNull(nameof(source));
  857. if (selector == null)
  858. throw Error.ArgumentNull(nameof(selector));
  859. return Core(source, selector, cancellationToken);
  860. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<int?>> selector, CancellationToken cancellationToken)
  861. {
  862. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  863. {
  864. while (await e.MoveNextAsync())
  865. {
  866. var v = await selector(e.Current).ConfigureAwait(false);
  867. if (v.HasValue)
  868. {
  869. long sum = v.GetValueOrDefault();
  870. long count = 1;
  871. checked
  872. {
  873. while (await e.MoveNextAsync())
  874. {
  875. v = await selector(e.Current).ConfigureAwait(false);
  876. if (v.HasValue)
  877. {
  878. sum += v.GetValueOrDefault();
  879. ++count;
  880. }
  881. }
  882. }
  883. return (double)sum / count;
  884. }
  885. }
  886. }
  887. return null;
  888. }
  889. }
  890. #if !NO_DEEP_CANCELLATION
  891. [GenerateAsyncOverload]
  892. private static ValueTask<double?> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<int?>> selector, CancellationToken cancellationToken = default)
  893. {
  894. if (source == null)
  895. throw Error.ArgumentNull(nameof(source));
  896. if (selector == null)
  897. throw Error.ArgumentNull(nameof(selector));
  898. return Core(source, selector, cancellationToken);
  899. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<int?>> selector, CancellationToken cancellationToken)
  900. {
  901. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  902. {
  903. while (await e.MoveNextAsync())
  904. {
  905. var v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  906. if (v.HasValue)
  907. {
  908. long sum = v.GetValueOrDefault();
  909. long count = 1;
  910. checked
  911. {
  912. while (await e.MoveNextAsync())
  913. {
  914. v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  915. if (v.HasValue)
  916. {
  917. sum += v.GetValueOrDefault();
  918. ++count;
  919. }
  920. }
  921. }
  922. return (double)sum / count;
  923. }
  924. }
  925. }
  926. return null;
  927. }
  928. }
  929. #endif
  930. /// <summary>
  931. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Long}" /> values.
  932. /// </summary>
  933. /// <param name="source">A sequence of <see cref="Nullable{Long}" /> values to calculate the average of.</param>
  934. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  935. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  936. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  937. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  938. public static ValueTask<double?> AverageAsync(this IAsyncEnumerable<long?> source, CancellationToken cancellationToken = default)
  939. {
  940. if (source == null)
  941. throw Error.ArgumentNull(nameof(source));
  942. return Core(source, cancellationToken);
  943. static async ValueTask<double?> Core(IAsyncEnumerable<long?> source, CancellationToken cancellationToken)
  944. {
  945. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  946. {
  947. while (await e.MoveNextAsync())
  948. {
  949. var v = e.Current;
  950. if (v.HasValue)
  951. {
  952. long sum = v.GetValueOrDefault();
  953. long count = 1;
  954. checked
  955. {
  956. while (await e.MoveNextAsync())
  957. {
  958. v = e.Current;
  959. if (v.HasValue)
  960. {
  961. sum += v.GetValueOrDefault();
  962. ++count;
  963. }
  964. }
  965. }
  966. return (double)sum / count;
  967. }
  968. }
  969. }
  970. return null;
  971. }
  972. }
  973. /// <summary>
  974. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Long}" /> values that are obtained by invoking a transform function on each element of the input sequence.
  975. /// </summary>
  976. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  977. /// <param name="source">A sequence of values to calculate the average of.</param>
  978. /// <param name="selector">A transform function to apply to each element.</param>
  979. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  980. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  981. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  982. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  983. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  984. public static ValueTask<double?> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, long?> selector, CancellationToken cancellationToken = default)
  985. {
  986. if (source == null)
  987. throw Error.ArgumentNull(nameof(source));
  988. if (selector == null)
  989. throw Error.ArgumentNull(nameof(selector));
  990. return Core(source, selector, cancellationToken);
  991. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, long?> selector, CancellationToken cancellationToken)
  992. {
  993. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  994. {
  995. while (await e.MoveNextAsync())
  996. {
  997. var v = selector(e.Current);
  998. if (v.HasValue)
  999. {
  1000. long sum = v.GetValueOrDefault();
  1001. long count = 1;
  1002. checked
  1003. {
  1004. while (await e.MoveNextAsync())
  1005. {
  1006. v = selector(e.Current);
  1007. if (v.HasValue)
  1008. {
  1009. sum += v.GetValueOrDefault();
  1010. ++count;
  1011. }
  1012. }
  1013. }
  1014. return (double)sum / count;
  1015. }
  1016. }
  1017. }
  1018. return null;
  1019. }
  1020. }
  1021. /// <summary>
  1022. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Long}"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  1023. /// </summary>
  1024. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  1025. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  1026. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  1027. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  1028. /// <returns>A ValueTask containing the average of the sequence of values, or <see langword="null"/> if the source sequence is empty.</returns>
  1029. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  1030. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1031. [GenerateAsyncOverload]
  1032. private static ValueTask<double?> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<long?>> selector, CancellationToken cancellationToken = default)
  1033. {
  1034. if (source == null)
  1035. throw Error.ArgumentNull(nameof(source));
  1036. if (selector == null)
  1037. throw Error.ArgumentNull(nameof(selector));
  1038. return Core(source, selector, cancellationToken);
  1039. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<long?>> selector, CancellationToken cancellationToken)
  1040. {
  1041. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1042. {
  1043. while (await e.MoveNextAsync())
  1044. {
  1045. var v = await selector(e.Current).ConfigureAwait(false);
  1046. if (v.HasValue)
  1047. {
  1048. long sum = v.GetValueOrDefault();
  1049. long count = 1;
  1050. checked
  1051. {
  1052. while (await e.MoveNextAsync())
  1053. {
  1054. v = await selector(e.Current).ConfigureAwait(false);
  1055. if (v.HasValue)
  1056. {
  1057. sum += v.GetValueOrDefault();
  1058. ++count;
  1059. }
  1060. }
  1061. }
  1062. return (double)sum / count;
  1063. }
  1064. }
  1065. }
  1066. return null;
  1067. }
  1068. }
  1069. #if !NO_DEEP_CANCELLATION
  1070. [GenerateAsyncOverload]
  1071. private static ValueTask<double?> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<long?>> selector, CancellationToken cancellationToken = default)
  1072. {
  1073. if (source == null)
  1074. throw Error.ArgumentNull(nameof(source));
  1075. if (selector == null)
  1076. throw Error.ArgumentNull(nameof(selector));
  1077. return Core(source, selector, cancellationToken);
  1078. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<long?>> selector, CancellationToken cancellationToken)
  1079. {
  1080. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1081. {
  1082. while (await e.MoveNextAsync())
  1083. {
  1084. var v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1085. if (v.HasValue)
  1086. {
  1087. long sum = v.GetValueOrDefault();
  1088. long count = 1;
  1089. checked
  1090. {
  1091. while (await e.MoveNextAsync())
  1092. {
  1093. v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1094. if (v.HasValue)
  1095. {
  1096. sum += v.GetValueOrDefault();
  1097. ++count;
  1098. }
  1099. }
  1100. }
  1101. return (double)sum / count;
  1102. }
  1103. }
  1104. }
  1105. return null;
  1106. }
  1107. }
  1108. #endif
  1109. /// <summary>
  1110. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Float}" /> values.
  1111. /// </summary>
  1112. /// <param name="source">A sequence of <see cref="Nullable{Float}" /> values to calculate the average of.</param>
  1113. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  1114. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  1115. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  1116. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  1117. public static ValueTask<float?> AverageAsync(this IAsyncEnumerable<float?> source, CancellationToken cancellationToken = default)
  1118. {
  1119. if (source == null)
  1120. throw Error.ArgumentNull(nameof(source));
  1121. return Core(source, cancellationToken);
  1122. static async ValueTask<float?> Core(IAsyncEnumerable<float?> source, CancellationToken cancellationToken)
  1123. {
  1124. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1125. {
  1126. while (await e.MoveNextAsync())
  1127. {
  1128. var v = e.Current;
  1129. if (v.HasValue)
  1130. {
  1131. double sum = v.GetValueOrDefault();
  1132. long count = 1;
  1133. checked
  1134. {
  1135. while (await e.MoveNextAsync())
  1136. {
  1137. v = e.Current;
  1138. if (v.HasValue)
  1139. {
  1140. sum += v.GetValueOrDefault();
  1141. ++count;
  1142. }
  1143. }
  1144. }
  1145. return (float)(sum / count);
  1146. }
  1147. }
  1148. }
  1149. return null;
  1150. }
  1151. }
  1152. /// <summary>
  1153. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Float}" /> values that are obtained by invoking a transform function on each element of the input sequence.
  1154. /// </summary>
  1155. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  1156. /// <param name="source">A sequence of values to calculate the average of.</param>
  1157. /// <param name="selector">A transform function to apply to each element.</param>
  1158. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  1159. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  1160. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  1161. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  1162. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1163. public static ValueTask<float?> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, float?> selector, CancellationToken cancellationToken = default)
  1164. {
  1165. if (source == null)
  1166. throw Error.ArgumentNull(nameof(source));
  1167. if (selector == null)
  1168. throw Error.ArgumentNull(nameof(selector));
  1169. return Core(source, selector, cancellationToken);
  1170. static async ValueTask<float?> Core(IAsyncEnumerable<TSource> source, Func<TSource, float?> selector, CancellationToken cancellationToken)
  1171. {
  1172. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1173. {
  1174. while (await e.MoveNextAsync())
  1175. {
  1176. var v = selector(e.Current);
  1177. if (v.HasValue)
  1178. {
  1179. double sum = v.GetValueOrDefault();
  1180. long count = 1;
  1181. checked
  1182. {
  1183. while (await e.MoveNextAsync())
  1184. {
  1185. v = selector(e.Current);
  1186. if (v.HasValue)
  1187. {
  1188. sum += v.GetValueOrDefault();
  1189. ++count;
  1190. }
  1191. }
  1192. }
  1193. return (float)(sum / count);
  1194. }
  1195. }
  1196. }
  1197. return null;
  1198. }
  1199. }
  1200. /// <summary>
  1201. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Float}"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  1202. /// </summary>
  1203. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  1204. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  1205. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  1206. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  1207. /// <returns>A ValueTask containing the average of the sequence of values, or <see langword="null"/> if the source sequence is empty.</returns>
  1208. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  1209. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1210. [GenerateAsyncOverload]
  1211. private static ValueTask<float?> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<float?>> selector, CancellationToken cancellationToken = default)
  1212. {
  1213. if (source == null)
  1214. throw Error.ArgumentNull(nameof(source));
  1215. if (selector == null)
  1216. throw Error.ArgumentNull(nameof(selector));
  1217. return Core(source, selector, cancellationToken);
  1218. static async ValueTask<float?> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<float?>> selector, CancellationToken cancellationToken)
  1219. {
  1220. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1221. {
  1222. while (await e.MoveNextAsync())
  1223. {
  1224. var v = await selector(e.Current).ConfigureAwait(false);
  1225. if (v.HasValue)
  1226. {
  1227. double sum = v.GetValueOrDefault();
  1228. long count = 1;
  1229. checked
  1230. {
  1231. while (await e.MoveNextAsync())
  1232. {
  1233. v = await selector(e.Current).ConfigureAwait(false);
  1234. if (v.HasValue)
  1235. {
  1236. sum += v.GetValueOrDefault();
  1237. ++count;
  1238. }
  1239. }
  1240. }
  1241. return (float)(sum / count);
  1242. }
  1243. }
  1244. }
  1245. return null;
  1246. }
  1247. }
  1248. #if !NO_DEEP_CANCELLATION
  1249. [GenerateAsyncOverload]
  1250. private static ValueTask<float?> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<float?>> selector, CancellationToken cancellationToken = default)
  1251. {
  1252. if (source == null)
  1253. throw Error.ArgumentNull(nameof(source));
  1254. if (selector == null)
  1255. throw Error.ArgumentNull(nameof(selector));
  1256. return Core(source, selector, cancellationToken);
  1257. static async ValueTask<float?> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<float?>> selector, CancellationToken cancellationToken)
  1258. {
  1259. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1260. {
  1261. while (await e.MoveNextAsync())
  1262. {
  1263. var v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1264. if (v.HasValue)
  1265. {
  1266. double sum = v.GetValueOrDefault();
  1267. long count = 1;
  1268. checked
  1269. {
  1270. while (await e.MoveNextAsync())
  1271. {
  1272. v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1273. if (v.HasValue)
  1274. {
  1275. sum += v.GetValueOrDefault();
  1276. ++count;
  1277. }
  1278. }
  1279. }
  1280. return (float)(sum / count);
  1281. }
  1282. }
  1283. }
  1284. return null;
  1285. }
  1286. }
  1287. #endif
  1288. /// <summary>
  1289. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Double}" /> values.
  1290. /// </summary>
  1291. /// <param name="source">A sequence of <see cref="Nullable{Double}" /> values to calculate the average of.</param>
  1292. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  1293. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  1294. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  1295. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  1296. public static ValueTask<double?> AverageAsync(this IAsyncEnumerable<double?> source, CancellationToken cancellationToken = default)
  1297. {
  1298. if (source == null)
  1299. throw Error.ArgumentNull(nameof(source));
  1300. return Core(source, cancellationToken);
  1301. static async ValueTask<double?> Core(IAsyncEnumerable<double?> source, CancellationToken cancellationToken)
  1302. {
  1303. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1304. {
  1305. while (await e.MoveNextAsync())
  1306. {
  1307. var v = e.Current;
  1308. if (v.HasValue)
  1309. {
  1310. double sum = v.GetValueOrDefault();
  1311. long count = 1;
  1312. checked
  1313. {
  1314. while (await e.MoveNextAsync())
  1315. {
  1316. v = e.Current;
  1317. if (v.HasValue)
  1318. {
  1319. sum += v.GetValueOrDefault();
  1320. ++count;
  1321. }
  1322. }
  1323. }
  1324. return sum / count;
  1325. }
  1326. }
  1327. }
  1328. return null;
  1329. }
  1330. }
  1331. /// <summary>
  1332. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Double}" /> values that are obtained by invoking a transform function on each element of the input sequence.
  1333. /// </summary>
  1334. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  1335. /// <param name="source">A sequence of values to calculate the average of.</param>
  1336. /// <param name="selector">A transform function to apply to each element.</param>
  1337. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  1338. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  1339. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  1340. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  1341. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1342. public static ValueTask<double?> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, double?> selector, CancellationToken cancellationToken = default)
  1343. {
  1344. if (source == null)
  1345. throw Error.ArgumentNull(nameof(source));
  1346. if (selector == null)
  1347. throw Error.ArgumentNull(nameof(selector));
  1348. return Core(source, selector, cancellationToken);
  1349. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, double?> selector, CancellationToken cancellationToken)
  1350. {
  1351. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1352. {
  1353. while (await e.MoveNextAsync())
  1354. {
  1355. var v = selector(e.Current);
  1356. if (v.HasValue)
  1357. {
  1358. double sum = v.GetValueOrDefault();
  1359. long count = 1;
  1360. checked
  1361. {
  1362. while (await e.MoveNextAsync())
  1363. {
  1364. v = selector(e.Current);
  1365. if (v.HasValue)
  1366. {
  1367. sum += v.GetValueOrDefault();
  1368. ++count;
  1369. }
  1370. }
  1371. }
  1372. return sum / count;
  1373. }
  1374. }
  1375. }
  1376. return null;
  1377. }
  1378. }
  1379. /// <summary>
  1380. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Double}"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  1381. /// </summary>
  1382. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  1383. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  1384. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  1385. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  1386. /// <returns>A ValueTask containing the average of the sequence of values, or <see langword="null"/> if the source sequence is empty.</returns>
  1387. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  1388. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1389. [GenerateAsyncOverload]
  1390. private static ValueTask<double?> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<double?>> selector, CancellationToken cancellationToken = default)
  1391. {
  1392. if (source == null)
  1393. throw Error.ArgumentNull(nameof(source));
  1394. if (selector == null)
  1395. throw Error.ArgumentNull(nameof(selector));
  1396. return Core(source, selector, cancellationToken);
  1397. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<double?>> selector, CancellationToken cancellationToken)
  1398. {
  1399. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1400. {
  1401. while (await e.MoveNextAsync())
  1402. {
  1403. var v = await selector(e.Current).ConfigureAwait(false);
  1404. if (v.HasValue)
  1405. {
  1406. double sum = v.GetValueOrDefault();
  1407. long count = 1;
  1408. checked
  1409. {
  1410. while (await e.MoveNextAsync())
  1411. {
  1412. v = await selector(e.Current).ConfigureAwait(false);
  1413. if (v.HasValue)
  1414. {
  1415. sum += v.GetValueOrDefault();
  1416. ++count;
  1417. }
  1418. }
  1419. }
  1420. return sum / count;
  1421. }
  1422. }
  1423. }
  1424. return null;
  1425. }
  1426. }
  1427. #if !NO_DEEP_CANCELLATION
  1428. [GenerateAsyncOverload]
  1429. private static ValueTask<double?> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<double?>> selector, CancellationToken cancellationToken = default)
  1430. {
  1431. if (source == null)
  1432. throw Error.ArgumentNull(nameof(source));
  1433. if (selector == null)
  1434. throw Error.ArgumentNull(nameof(selector));
  1435. return Core(source, selector, cancellationToken);
  1436. static async ValueTask<double?> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<double?>> selector, CancellationToken cancellationToken)
  1437. {
  1438. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1439. {
  1440. while (await e.MoveNextAsync())
  1441. {
  1442. var v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1443. if (v.HasValue)
  1444. {
  1445. double sum = v.GetValueOrDefault();
  1446. long count = 1;
  1447. checked
  1448. {
  1449. while (await e.MoveNextAsync())
  1450. {
  1451. v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1452. if (v.HasValue)
  1453. {
  1454. sum += v.GetValueOrDefault();
  1455. ++count;
  1456. }
  1457. }
  1458. }
  1459. return sum / count;
  1460. }
  1461. }
  1462. }
  1463. return null;
  1464. }
  1465. }
  1466. #endif
  1467. /// <summary>
  1468. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Decimal}" /> values.
  1469. /// </summary>
  1470. /// <param name="source">A sequence of <see cref="Nullable{Decimal}" /> values to calculate the average of.</param>
  1471. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  1472. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values.</returns>
  1473. /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
  1474. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  1475. public static ValueTask<decimal?> AverageAsync(this IAsyncEnumerable<decimal?> source, CancellationToken cancellationToken = default)
  1476. {
  1477. if (source == null)
  1478. throw Error.ArgumentNull(nameof(source));
  1479. return Core(source, cancellationToken);
  1480. static async ValueTask<decimal?> Core(IAsyncEnumerable<decimal?> source, CancellationToken cancellationToken)
  1481. {
  1482. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1483. {
  1484. while (await e.MoveNextAsync())
  1485. {
  1486. var v = e.Current;
  1487. if (v.HasValue)
  1488. {
  1489. decimal sum = v.GetValueOrDefault();
  1490. long count = 1;
  1491. checked
  1492. {
  1493. while (await e.MoveNextAsync())
  1494. {
  1495. v = e.Current;
  1496. if (v.HasValue)
  1497. {
  1498. sum += v.GetValueOrDefault();
  1499. ++count;
  1500. }
  1501. }
  1502. }
  1503. return sum / count;
  1504. }
  1505. }
  1506. }
  1507. return null;
  1508. }
  1509. }
  1510. /// <summary>
  1511. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Decimal}" /> values that are obtained by invoking a transform function on each element of the input sequence.
  1512. /// </summary>
  1513. /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
  1514. /// <param name="source">A sequence of values to calculate the average of.</param>
  1515. /// <param name="selector">A transform function to apply to each element.</param>
  1516. /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
  1517. /// <returns>An async-enumerable sequence containing a single element with the average of the sequence of values, or null if the source sequence is empty or contains only values that are null.</returns>
  1518. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
  1519. /// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
  1520. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1521. public static ValueTask<decimal?> AverageAsync<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, decimal?> selector, CancellationToken cancellationToken = default)
  1522. {
  1523. if (source == null)
  1524. throw Error.ArgumentNull(nameof(source));
  1525. if (selector == null)
  1526. throw Error.ArgumentNull(nameof(selector));
  1527. return Core(source, selector, cancellationToken);
  1528. static async ValueTask<decimal?> Core(IAsyncEnumerable<TSource> source, Func<TSource, decimal?> selector, CancellationToken cancellationToken)
  1529. {
  1530. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1531. {
  1532. while (await e.MoveNextAsync())
  1533. {
  1534. var v = selector(e.Current);
  1535. if (v.HasValue)
  1536. {
  1537. decimal sum = v.GetValueOrDefault();
  1538. long count = 1;
  1539. checked
  1540. {
  1541. while (await e.MoveNextAsync())
  1542. {
  1543. v = selector(e.Current);
  1544. if (v.HasValue)
  1545. {
  1546. sum += v.GetValueOrDefault();
  1547. ++count;
  1548. }
  1549. }
  1550. }
  1551. return sum / count;
  1552. }
  1553. }
  1554. }
  1555. return null;
  1556. }
  1557. }
  1558. /// <summary>
  1559. /// Computes the average of an async-enumerable sequence of <see cref="Nullable{Decimal}"/> values that are obtained by invoking an asynchronous transform function on each element of the source sequence and awaiting the result.
  1560. /// </summary>
  1561. /// <typeparam name="TSource">The type of elements in the source sequence.</typeparam>
  1562. /// <param name="source">An async-enumerable sequence of values to compute the average of.</param>
  1563. /// <param name="selector">A transform function to invoke and await on each element of the source sequence.</param>
  1564. /// <param name="cancellationToken">An optional cancellation token for cancelling the sequence at any time.</param>
  1565. /// <returns>A ValueTask containing the average of the sequence of values, or <see langword="null"/> if the source sequence is empty.</returns>
  1566. /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is <see langword="null"/>.</exception>
  1567. /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
  1568. [GenerateAsyncOverload]
  1569. private static ValueTask<decimal?> AverageAwaitAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<decimal?>> selector, CancellationToken cancellationToken = default)
  1570. {
  1571. if (source == null)
  1572. throw Error.ArgumentNull(nameof(source));
  1573. if (selector == null)
  1574. throw Error.ArgumentNull(nameof(selector));
  1575. return Core(source, selector, cancellationToken);
  1576. static async ValueTask<decimal?> Core(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<decimal?>> selector, CancellationToken cancellationToken)
  1577. {
  1578. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1579. {
  1580. while (await e.MoveNextAsync())
  1581. {
  1582. var v = await selector(e.Current).ConfigureAwait(false);
  1583. if (v.HasValue)
  1584. {
  1585. decimal sum = v.GetValueOrDefault();
  1586. long count = 1;
  1587. checked
  1588. {
  1589. while (await e.MoveNextAsync())
  1590. {
  1591. v = await selector(e.Current).ConfigureAwait(false);
  1592. if (v.HasValue)
  1593. {
  1594. sum += v.GetValueOrDefault();
  1595. ++count;
  1596. }
  1597. }
  1598. }
  1599. return sum / count;
  1600. }
  1601. }
  1602. }
  1603. return null;
  1604. }
  1605. }
  1606. #if !NO_DEEP_CANCELLATION
  1607. [GenerateAsyncOverload]
  1608. private static ValueTask<decimal?> AverageAwaitWithCancellationAsyncCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<decimal?>> selector, CancellationToken cancellationToken = default)
  1609. {
  1610. if (source == null)
  1611. throw Error.ArgumentNull(nameof(source));
  1612. if (selector == null)
  1613. throw Error.ArgumentNull(nameof(selector));
  1614. return Core(source, selector, cancellationToken);
  1615. static async ValueTask<decimal?> Core(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<decimal?>> selector, CancellationToken cancellationToken)
  1616. {
  1617. await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false))
  1618. {
  1619. while (await e.MoveNextAsync())
  1620. {
  1621. var v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1622. if (v.HasValue)
  1623. {
  1624. decimal sum = v.GetValueOrDefault();
  1625. long count = 1;
  1626. checked
  1627. {
  1628. while (await e.MoveNextAsync())
  1629. {
  1630. v = await selector(e.Current, cancellationToken).ConfigureAwait(false);
  1631. if (v.HasValue)
  1632. {
  1633. sum += v.GetValueOrDefault();
  1634. ++count;
  1635. }
  1636. }
  1637. }
  1638. return sum / count;
  1639. }
  1640. }
  1641. }
  1642. return null;
  1643. }
  1644. }
  1645. #endif
  1646. }
  1647. }