diff --git a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md index 5956148c34..9c1c06a137 100644 --- a/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md +++ b/Ix.NET/Documentation/adr/0002-System-Linq-Async-In-Net10.md @@ -32,12 +32,15 @@ There are also a couple of cases where functionality simply has not been reprodu `System.Linq.Async` also defined some interfaces that are not replicated in `System.Linq.AsyncEnumerable`. `System.Linq.Async` defined `IAsyncGrouping` to act as the return type for `GroupBy`. `System.Linq.AsyncEnumerable` just uses `IAsyncEnumerable>`, which is not quite the same: this enables asynchronous iteration of the sequence of groups, but each invidual group's contents are not asynchronously enumerable. `IAsyncGrouping` enabled asynchronous enumeration of both. In practice, `System.Linq.Async` did not exploit this: it fully enumerated the whole source list to split items into groups before returning the first group, so although it compelled you to enumerate at both levels (e.g., with nested `await foreach` loops), in reality only the outer level was asynchronous in practice. So this interface added complication without real benefits. There is also `IAsyncIListProvider`, an interface that arguably should not have been public in the first place, serving only to enable some internal optimizations. (Apparently it was public in `System.Linq.Async` because it is also used in other parts of Ix.NET.) +A further complication is that some methods in `System.Interactive.Async` clash with methods in `System.Linq.AsyncEnumerable`. For example, `MaxByAsync` and `MinByAsync`. Originally `MinBy` and `MaxBy` were unique to Rx.NET and Ix.NET. But .NET 6.0 added operators with these names to LINQ to Objects. Confusingly, they were slightly different: the Rx.NET and Ix.NET versions recognize that there might not be a single minimum or maximum value, and thus provide a collection of all the entries that are at the maximum value, but the .NET runtime class library versions just pick one arbitrary winner. So at this point, `System.Interactive` renamed its versions to `MinByWithTies` and `MaxByWithTies`. Unfortunately that same change wasn't made in `System.Interactive.Async`, so we now have the same situation with `System.Linq.AsyncEnumerable`: the .NET runtime class libraries now define `MinByAsync` and `MaxByAsync` extension methods for `IAsyncEnumerable`, and these take the same arguments as the ones in `System.Interactive.Async`, but have a different return type, and have different behaviour! + + ## Decision -The next `System.Linq.Async` release will: +The next Ix.NET release will: -1. add a reference to `System.Linq.AsyncEnumerable` and `System.Interactive.Async` -2. remove from publicly visible API (ref assemblies) all `IAsyncEnumerable` extension methods for which direct replacements exist +1. add a reference to `System.Linq.AsyncEnumerable` and `System.Interactive.Async` in `System.Linq.Async` +2. remove from `System.Linq.Async`'s and `System.Interactive.Async`'s publicly visible API (ref assemblies) all `IAsyncEnumerable` extension methods for which direct replacements exist (adding `MinByWithTiesAsync` and `MaxByWithTiesAsync` for the case where the new .NET runtime library methods actually have slightly different functionality) 3. add [Obsolete] attribute for members of `AsyncEnumerable` for which `System.Linq.AsyncEnumerable` offers replacements that require code changes to use (e.g., `WhereAwait`, which is replaced by an overload of `Where`) 4. `AsyncEnumerable` methods that are a bad idea and that should probably have never existing (the ones that do sync over async, e.g. `ToEnumerable`) are marked as `Obsolete` and will not be replaced; note that although `ToObservable` has issues that meant the .NET team decided not to replicate it, the main issue is that it embeds opinions, and not that there's anything fundamentally broken about it, so we do not include `ToObservable` in this category 5. remaining methods of `AsyncEnumerable` (where `System.Linq.AsyncEnumerable` offers no equivalent) are removed from the publicly visible API of `System.Linq.Async`, with identical replacements being defined by `AsyncEnumerableEx` in `System.Interactive @@ -60,6 +63,14 @@ In summary, each of the features previously provided by `System.Linq.Async` will * Method hidden in `ref` assembly, available in `System.Interactive.Async` * Method visible but marked as `Obsolete`, with new but slightly different equivalent available in `System.Linq.AsyncEnumerable` +### TFMs + +We want to keep the TFMs for all Ix.NET packages exactly the same in this version, because the only reason for Ix.NET v7 to exist is to deal with the new existence of `System.Linq.AsyncEnumerable`. + +There is one issue with this. If a project has a `net6.0` target and tries to use `System.Linq.AsyncEnumerable`, it produces a build warning, saying that it's not supported on that runtime. Although we don't like having this build warning, we are currently intending not to do anything about it, because we believe that messing with the TFMs is likely to have unintended consequences. + +If it turns out that this does cause problems, we'll revisit this and do a new release. + ## Consequences Binary compatibility is maintained: any code that was built against `System.Linq.Async` v6 but which finds itself running against v7 at runtime should continue to work exactly as before. diff --git a/Ix.NET/Source/ApiCompare/ApiCompare.csproj b/Ix.NET/Source/ApiCompare/ApiCompare.csproj index 8103ccc207..2f71f4d751 100644 --- a/Ix.NET/Source/ApiCompare/ApiCompare.csproj +++ b/Ix.NET/Source/ApiCompare/ApiCompare.csproj @@ -3,6 +3,7 @@ Exe net8.0 + false diff --git a/Ix.NET/Source/AsyncQueryableGenerator.t4 b/Ix.NET/Source/AsyncQueryableGenerator.t4 index 618306f840..d62a761e8d 100644 --- a/Ix.NET/Source/AsyncQueryableGenerator.t4 +++ b/Ix.NET/Source/AsyncQueryableGenerator.t4 @@ -283,6 +283,10 @@ foreach (var m in asyncEnumerableType.GetMethods() cast = "(" + toQuoted(m.ReturnType, null, 0) + ")"; } } + else + { + continue; // this skips ToObservable, which we can't represent in a query + } } var n = 0; diff --git a/Ix.NET/Source/Benchmarks.System.Interactive/Benchmarks.System.Interactive.csproj b/Ix.NET/Source/Benchmarks.System.Interactive/Benchmarks.System.Interactive.csproj index 032ec88ed9..b87e17c335 100644 --- a/Ix.NET/Source/Benchmarks.System.Interactive/Benchmarks.System.Interactive.csproj +++ b/Ix.NET/Source/Benchmarks.System.Interactive/Benchmarks.System.Interactive.csproj @@ -3,6 +3,7 @@ Exe net8.0 + false true Current Sources;Ix.net 3.1.1;Ix.net 3.2 diff --git a/Ix.NET/Source/FasterLinq/FasterLinq.csproj b/Ix.NET/Source/FasterLinq/FasterLinq.csproj index 5758ba8fc1..7355849547 100644 --- a/Ix.NET/Source/FasterLinq/FasterLinq.csproj +++ b/Ix.NET/Source/FasterLinq/FasterLinq.csproj @@ -3,6 +3,7 @@ Exe net8.0 + false $(NoWarn);IDE0007;IDE0034;IDE0040;IDE0063;IDE0090;IDE1006 diff --git a/Ix.NET/Source/Ix.NET.sln b/Ix.NET/Source/Ix.NET.sln index b6e3fb52ad..21f6eb3b2a 100644 --- a/Ix.NET/Source/Ix.NET.sln +++ b/Ix.NET/Source/Ix.NET.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.2.32131.331 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11205.157 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{87534290-A7A6-47A4-9A3A-D0D21A9AD1D4}" ProjectSection(SolutionItems) = preProject @@ -11,6 +11,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B733D97A-F1ED-4FC3-BF8E-9AC47A89DE96}" ProjectSection(SolutionItems) = preProject ..\..\.editorconfig = ..\..\.editorconfig + AsyncQueryableGenerator.t4 = AsyncQueryableGenerator.t4 ..\..\azure-pipelines.ix.yml = ..\..\azure-pipelines.ix.yml CodeCoverage.runsettings = CodeCoverage.runsettings Directory.build.props = Directory.build.props @@ -76,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Linq.Async.SourceGen EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.System.Interactive.ApiApprovals", "Tests.System.Interactive.ApiApprovals\Tests.System.Interactive.ApiApprovals.csproj", "{CD146918-6465-4D5B-B6B7-3F9803095EBD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Interactive.Async", "refs\System.Interactive.Async\System.Interactive.Async.csproj", "{74613134-0799-190D-7023-EC9A28B3A1F2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -156,6 +159,10 @@ Global {CD146918-6465-4D5B-B6B7-3F9803095EBD}.Debug|Any CPU.Build.0 = Debug|Any CPU {CD146918-6465-4D5B-B6B7-3F9803095EBD}.Release|Any CPU.ActiveCfg = Release|Any CPU {CD146918-6465-4D5B-B6B7-3F9803095EBD}.Release|Any CPU.Build.0 = Release|Any CPU + {74613134-0799-190D-7023-EC9A28B3A1F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74613134-0799-190D-7023-EC9A28B3A1F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74613134-0799-190D-7023-EC9A28B3A1F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74613134-0799-190D-7023-EC9A28B3A1F2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -180,6 +187,7 @@ Global {1754B36C-D0DB-4E5D-8C30-1F116046DC0F} = {A3D72E6E-4ADA-42E0-8B2A-055B1F244281} {5C26D649-5ED4-49EE-AFBD-8FA8F12C4AE4} = {80EFE3A1-1414-42EA-949B-1B5370A1B2EA} {CD146918-6465-4D5B-B6B7-3F9803095EBD} = {87534290-A7A6-47A4-9A3A-D0D21A9AD1D4} + {74613134-0799-190D-7023-EC9A28B3A1F2} = {A3D72E6E-4ADA-42E0-8B2A-055B1F244281} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {AF70B0C6-C9D9-43B1-9BE4-08720EC1B7B7} diff --git a/Ix.NET/Source/Playground/Playground.csproj b/Ix.NET/Source/Playground/Playground.csproj index 170a3bd343..1c90ded667 100644 --- a/Ix.NET/Source/Playground/Playground.csproj +++ b/Ix.NET/Source/Playground/Playground.csproj @@ -3,6 +3,7 @@ Exe net8.0 + false diff --git a/Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs b/Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs index 856cf3513e..0e03cfdfd1 100644 --- a/Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs +++ b/Ix.NET/Source/System.Interactive.Async.Providers/System/Linq/AsyncQueryableEx.Generated.cs @@ -30,6 +30,500 @@ public static IAsyncQueryable Amb(this IAsyncQueryable(Expression.Call(Amb__TSource__2__0(typeof(TSource)), first.Expression, GetSourceExpression(second))); } + private static MethodInfo? s_AsAsyncEnumerable__TSource__1__0; + + private static MethodInfo AsAsyncEnumerable__TSource__1__0(Type TSource) => + (s_AsAsyncEnumerable__TSource__1__0 ?? + (s_AsAsyncEnumerable__TSource__1__0 = new Func, IAsyncQueryable>(AsAsyncEnumerable).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static IAsyncQueryable AsAsyncEnumerable(this IAsyncQueryable source) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + + return source.Provider.CreateQuery(Expression.Call(AsAsyncEnumerable__TSource__1__0(typeof(TSource)), source.Expression)); + } + + private static MethodInfo? s_AverageAsync__TSource__3__0; + + private static MethodInfo AverageAsync__TSource__3__0(Type TSource) => + (s_AverageAsync__TSource__3__0 ?? + (s_AverageAsync__TSource__3__0 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__0(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__1; + + private static MethodInfo AverageAsync__TSource__3__1(Type TSource) => + (s_AverageAsync__TSource__3__1 ?? + (s_AverageAsync__TSource__3__1 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__1(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__2; + + private static MethodInfo AverageAsync__TSource__3__2(Type TSource) => + (s_AverageAsync__TSource__3__2 ?? + (s_AverageAsync__TSource__3__2 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__2(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__3; + + private static MethodInfo AverageAsync__TSource__3__3(Type TSource) => + (s_AverageAsync__TSource__3__3 ?? + (s_AverageAsync__TSource__3__3 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__3(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__4; + + private static MethodInfo AverageAsync__TSource__3__4(Type TSource) => + (s_AverageAsync__TSource__3__4 ?? + (s_AverageAsync__TSource__3__4 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__4(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__5; + + private static MethodInfo AverageAsync__TSource__3__5(Type TSource) => + (s_AverageAsync__TSource__3__5 ?? + (s_AverageAsync__TSource__3__5 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__5(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__6; + + private static MethodInfo AverageAsync__TSource__3__6(Type TSource) => + (s_AverageAsync__TSource__3__6 ?? + (s_AverageAsync__TSource__3__6 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__6(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__7; + + private static MethodInfo AverageAsync__TSource__3__7(Type TSource) => + (s_AverageAsync__TSource__3__7 ?? + (s_AverageAsync__TSource__3__7 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__7(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__8; + + private static MethodInfo AverageAsync__TSource__3__8(Type TSource) => + (s_AverageAsync__TSource__3__8 ?? + (s_AverageAsync__TSource__3__8 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__8(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__9; + + private static MethodInfo AverageAsync__TSource__3__9(Type TSource) => + (s_AverageAsync__TSource__3__9 ?? + (s_AverageAsync__TSource__3__9 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__9(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__10; + + private static MethodInfo AverageAsync__TSource__3__10(Type TSource) => + (s_AverageAsync__TSource__3__10 ?? + (s_AverageAsync__TSource__3__10 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__10(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__11; + + private static MethodInfo AverageAsync__TSource__3__11(Type TSource) => + (s_AverageAsync__TSource__3__11 ?? + (s_AverageAsync__TSource__3__11 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__11(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__12; + + private static MethodInfo AverageAsync__TSource__3__12(Type TSource) => + (s_AverageAsync__TSource__3__12 ?? + (s_AverageAsync__TSource__3__12 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__12(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__13; + + private static MethodInfo AverageAsync__TSource__3__13(Type TSource) => + (s_AverageAsync__TSource__3__13 ?? + (s_AverageAsync__TSource__3__13 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__13(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__14; + + private static MethodInfo AverageAsync__TSource__3__14(Type TSource) => + (s_AverageAsync__TSource__3__14 ?? + (s_AverageAsync__TSource__3__14 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__14(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__15; + + private static MethodInfo AverageAsync__TSource__3__15(Type TSource) => + (s_AverageAsync__TSource__3__15 ?? + (s_AverageAsync__TSource__3__15 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__15(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__16; + + private static MethodInfo AverageAsync__TSource__3__16(Type TSource) => + (s_AverageAsync__TSource__3__16 ?? + (s_AverageAsync__TSource__3__16 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__16(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__17; + + private static MethodInfo AverageAsync__TSource__3__17(Type TSource) => + (s_AverageAsync__TSource__3__17 ?? + (s_AverageAsync__TSource__3__17 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__17(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__18; + + private static MethodInfo AverageAsync__TSource__3__18(Type TSource) => + (s_AverageAsync__TSource__3__18 ?? + (s_AverageAsync__TSource__3__18 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__18(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__19; + + private static MethodInfo AverageAsync__TSource__3__19(Type TSource) => + (s_AverageAsync__TSource__3__19 ?? + (s_AverageAsync__TSource__3__19 = new Func, Expression>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__19(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__20; + + private static MethodInfo AverageAsync__TSource__3__20(Type TSource) => + (s_AverageAsync__TSource__3__20 ?? + (s_AverageAsync__TSource__3__20 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__20(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__21; + + private static MethodInfo AverageAsync__TSource__3__21(Type TSource) => + (s_AverageAsync__TSource__3__21 ?? + (s_AverageAsync__TSource__3__21 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__21(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__22; + + private static MethodInfo AverageAsync__TSource__3__22(Type TSource) => + (s_AverageAsync__TSource__3__22 ?? + (s_AverageAsync__TSource__3__22 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__22(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__23; + + private static MethodInfo AverageAsync__TSource__3__23(Type TSource) => + (s_AverageAsync__TSource__3__23 ?? + (s_AverageAsync__TSource__3__23 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__23(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__24; + + private static MethodInfo AverageAsync__TSource__3__24(Type TSource) => + (s_AverageAsync__TSource__3__24 ?? + (s_AverageAsync__TSource__3__24 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__24(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__25; + + private static MethodInfo AverageAsync__TSource__3__25(Type TSource) => + (s_AverageAsync__TSource__3__25 ?? + (s_AverageAsync__TSource__3__25 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__25(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__26; + + private static MethodInfo AverageAsync__TSource__3__26(Type TSource) => + (s_AverageAsync__TSource__3__26 ?? + (s_AverageAsync__TSource__3__26 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__26(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__27; + + private static MethodInfo AverageAsync__TSource__3__27(Type TSource) => + (s_AverageAsync__TSource__3__27 ?? + (s_AverageAsync__TSource__3__27 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__27(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__28; + + private static MethodInfo AverageAsync__TSource__3__28(Type TSource) => + (s_AverageAsync__TSource__3__28 ?? + (s_AverageAsync__TSource__3__28 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__28(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_AverageAsync__TSource__3__29; + + private static MethodInfo AverageAsync__TSource__3__29(Type TSource) => + (s_AverageAsync__TSource__3__29 ?? + (s_AverageAsync__TSource__3__29 = new Func, Expression>>, CancellationToken, ValueTask>(AverageAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource); + + public static ValueTask AverageAsync(this IAsyncQueryable source, Expression>> selector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (selector == null) + throw new ArgumentNullException(nameof(selector)); + + return source.Provider.ExecuteAsync(Expression.Call(AverageAsync__TSource__3__29(typeof(TSource)), source.Expression, selector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + private static MethodInfo? s_Buffer__TSource__2__0; private static MethodInfo Buffer__TSource__2__0(Type TSource) => @@ -806,6 +1300,102 @@ public static ValueTask> MaxByAsync(this IAsyncQue return source.Provider.ExecuteAsync>(Expression.Call(MaxByAsync__TSource_TKey__4__2(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); } + private static MethodInfo? s_MaxByWithTiesAsync__TSource_TKey__3__0; + + private static MethodInfo MaxByWithTiesAsync__TSource_TKey__3__0(Type TSource, Type TKey) => + (s_MaxByWithTiesAsync__TSource_TKey__3__0 ?? + (s_MaxByWithTiesAsync__TSource_TKey__3__0 = new Func, Expression>>, CancellationToken, ValueTask>>(MaxByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MaxByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MaxByWithTiesAsync__TSource_TKey__3__0(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MaxByWithTiesAsync__TSource_TKey__3__1; + + private static MethodInfo MaxByWithTiesAsync__TSource_TKey__3__1(Type TSource, Type TKey) => + (s_MaxByWithTiesAsync__TSource_TKey__3__1 ?? + (s_MaxByWithTiesAsync__TSource_TKey__3__1 = new Func, Expression>, CancellationToken, ValueTask>>(MaxByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MaxByWithTiesAsync(this IAsyncQueryable source, Expression> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MaxByWithTiesAsync__TSource_TKey__3__1(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MaxByWithTiesAsync__TSource_TKey__3__2; + + private static MethodInfo MaxByWithTiesAsync__TSource_TKey__3__2(Type TSource, Type TKey) => + (s_MaxByWithTiesAsync__TSource_TKey__3__2 ?? + (s_MaxByWithTiesAsync__TSource_TKey__3__2 = new Func, Expression>>, CancellationToken, ValueTask>>(MaxByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MaxByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MaxByWithTiesAsync__TSource_TKey__3__2(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MaxByWithTiesAsync__TSource_TKey__4__0; + + private static MethodInfo MaxByWithTiesAsync__TSource_TKey__4__0(Type TSource, Type TKey) => + (s_MaxByWithTiesAsync__TSource_TKey__4__0 ?? + (s_MaxByWithTiesAsync__TSource_TKey__4__0 = new Func, Expression>>, IComparer, CancellationToken, ValueTask>>(MaxByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MaxByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MaxByWithTiesAsync__TSource_TKey__4__0(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MaxByWithTiesAsync__TSource_TKey__4__1; + + private static MethodInfo MaxByWithTiesAsync__TSource_TKey__4__1(Type TSource, Type TKey) => + (s_MaxByWithTiesAsync__TSource_TKey__4__1 ?? + (s_MaxByWithTiesAsync__TSource_TKey__4__1 = new Func, Expression>, IComparer, CancellationToken, ValueTask>>(MaxByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MaxByWithTiesAsync(this IAsyncQueryable source, Expression> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MaxByWithTiesAsync__TSource_TKey__4__1(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MaxByWithTiesAsync__TSource_TKey__4__2; + + private static MethodInfo MaxByWithTiesAsync__TSource_TKey__4__2(Type TSource, Type TKey) => + (s_MaxByWithTiesAsync__TSource_TKey__4__2 ?? + (s_MaxByWithTiesAsync__TSource_TKey__4__2 = new Func, Expression>>, IComparer, CancellationToken, ValueTask>>(MaxByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MaxByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MaxByWithTiesAsync__TSource_TKey__4__2(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + private static MethodInfo? s_Merge__TSource__1__0; private static MethodInfo Merge__TSource__1__0(Type TSource) => @@ -930,6 +1520,102 @@ public static ValueTask> MinByAsync(this IAsyncQue return source.Provider.ExecuteAsync>(Expression.Call(MinByAsync__TSource_TKey__4__2(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); } + private static MethodInfo? s_MinByWithTiesAsync__TSource_TKey__3__0; + + private static MethodInfo MinByWithTiesAsync__TSource_TKey__3__0(Type TSource, Type TKey) => + (s_MinByWithTiesAsync__TSource_TKey__3__0 ?? + (s_MinByWithTiesAsync__TSource_TKey__3__0 = new Func, Expression>>, CancellationToken, ValueTask>>(MinByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MinByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MinByWithTiesAsync__TSource_TKey__3__0(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MinByWithTiesAsync__TSource_TKey__3__1; + + private static MethodInfo MinByWithTiesAsync__TSource_TKey__3__1(Type TSource, Type TKey) => + (s_MinByWithTiesAsync__TSource_TKey__3__1 ?? + (s_MinByWithTiesAsync__TSource_TKey__3__1 = new Func, Expression>, CancellationToken, ValueTask>>(MinByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MinByWithTiesAsync(this IAsyncQueryable source, Expression> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MinByWithTiesAsync__TSource_TKey__3__1(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MinByWithTiesAsync__TSource_TKey__3__2; + + private static MethodInfo MinByWithTiesAsync__TSource_TKey__3__2(Type TSource, Type TKey) => + (s_MinByWithTiesAsync__TSource_TKey__3__2 ?? + (s_MinByWithTiesAsync__TSource_TKey__3__2 = new Func, Expression>>, CancellationToken, ValueTask>>(MinByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MinByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MinByWithTiesAsync__TSource_TKey__3__2(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MinByWithTiesAsync__TSource_TKey__4__0; + + private static MethodInfo MinByWithTiesAsync__TSource_TKey__4__0(Type TSource, Type TKey) => + (s_MinByWithTiesAsync__TSource_TKey__4__0 ?? + (s_MinByWithTiesAsync__TSource_TKey__4__0 = new Func, Expression>>, IComparer, CancellationToken, ValueTask>>(MinByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MinByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MinByWithTiesAsync__TSource_TKey__4__0(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MinByWithTiesAsync__TSource_TKey__4__1; + + private static MethodInfo MinByWithTiesAsync__TSource_TKey__4__1(Type TSource, Type TKey) => + (s_MinByWithTiesAsync__TSource_TKey__4__1 ?? + (s_MinByWithTiesAsync__TSource_TKey__4__1 = new Func, Expression>, IComparer, CancellationToken, ValueTask>>(MinByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MinByWithTiesAsync(this IAsyncQueryable source, Expression> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MinByWithTiesAsync__TSource_TKey__4__1(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + + private static MethodInfo? s_MinByWithTiesAsync__TSource_TKey__4__2; + + private static MethodInfo MinByWithTiesAsync__TSource_TKey__4__2(Type TSource, Type TKey) => + (s_MinByWithTiesAsync__TSource_TKey__4__2 ?? + (s_MinByWithTiesAsync__TSource_TKey__4__2 = new Func, Expression>>, IComparer, CancellationToken, ValueTask>>(MinByWithTiesAsync).GetMethodInfo()!.GetGenericMethodDefinition())).MakeGenericMethod(TSource, TKey); + + public static ValueTask> MinByWithTiesAsync(this IAsyncQueryable source, Expression>> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw new ArgumentNullException(nameof(source)); + if (keySelector == null) + throw new ArgumentNullException(nameof(keySelector)); + + return source.Provider.ExecuteAsync>(Expression.Call(MinByWithTiesAsync__TSource_TKey__4__2(typeof(TSource), typeof(TKey)), source.Expression, keySelector, Expression.Constant(comparer, typeof(IComparer)), Expression.Constant(cancellationToken, typeof(CancellationToken))), cancellationToken); + } + private static MethodInfo? s_OnErrorResumeNext__TSource__2__0; private static MethodInfo OnErrorResumeNext__TSource__2__0(Type TSource) => diff --git a/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MaxByWithTies.cs b/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MaxByWithTies.cs new file mode 100644 index 0000000000..8f04f259f5 --- /dev/null +++ b/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MaxByWithTies.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Tests +{ + public class MaxByWithTies : AsyncEnumerableExTests + { + [Fact] + public async Task MaxByWithTies_Null() + { + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(default(IAsyncEnumerable), x => x).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(Return42, default(Func)).AsTask()); + + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(default(IAsyncEnumerable), x => x, Comparer.Default).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(Return42, default(Func), Comparer.Default).AsTask()); + + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(default(IAsyncEnumerable), x => x, CancellationToken.None).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(Return42, default(Func), CancellationToken.None).AsTask()); + + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(default(IAsyncEnumerable), x => x, Comparer.Default, CancellationToken.None).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MaxByWithTiesAsync(Return42, default(Func), Comparer.Default, CancellationToken.None).AsTask()); + } + + [Fact] + public async Task MaxByWithTies1Async() + { + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxByWithTiesAsync(x => x / 2); + var res = await xs; + + Assert.True(res.SequenceEqual([7, 6])); + } + + [Fact] + public async Task MaxByWithTies2() + { + var xs = Array.Empty().ToAsyncEnumerable().MaxByWithTiesAsync(x => x / 2); + + await AssertThrowsAsync(xs.AsTask()); + } + + [Fact] + public async Task MaxByWithTies3() + { + var ex = new Exception("Bang!"); + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxByWithTiesAsync(x => { if (x == 3) throw ex; return x; }); + + await AssertThrowsAsync(xs, ex); + } + + [Fact] + public async Task MaxByWithTies4() + { + var ex = new Exception("Bang!"); + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MaxByWithTiesAsync(x => { if (x == 4) throw ex; return x; }); + + await AssertThrowsAsync(xs, ex); + } + + [Fact] + public async Task MaxByWithTies5() + { + var ex = new Exception("Bang!"); + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().Concat(Throw(ex)).MaxByWithTiesAsync(x => x, Comparer.Default); + + await AssertThrowsAsync(xs, ex); + } + } +} diff --git a/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MinByWithTies.cs b/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MinByWithTies.cs new file mode 100644 index 0000000000..a1e147b0c5 --- /dev/null +++ b/Ix.NET/Source/System.Interactive.Async.Tests/System/Linq/Operators/MinByWithTies.cs @@ -0,0 +1,76 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT License. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Tests +{ + public class MinByWithTies : AsyncEnumerableExTests + { + [Fact] + public async Task MinByWithTies_Null() + { + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(default(IAsyncEnumerable), x => x).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(Return42, default(Func)).AsTask()); + + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(default(IAsyncEnumerable), x => x, Comparer.Default).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(Return42, default(Func), Comparer.Default).AsTask()); + + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(default(IAsyncEnumerable), x => x, CancellationToken.None).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(Return42, default(Func), CancellationToken.None).AsTask()); + + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(default(IAsyncEnumerable), x => x, Comparer.Default, CancellationToken.None).AsTask()); + await Assert.ThrowsAsync(() => AsyncEnumerableEx.MinByWithTiesAsync(Return42, default(Func), Comparer.Default, CancellationToken.None).AsTask()); + } + + [Fact] + public async Task MinByWithTies1Async() + { + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinByWithTiesAsync(x => x / 2); + var res = await xs; + + Assert.True(res.SequenceEqual([3, 2])); + } + + [Fact] + public async Task MinByWithTies2Async() + { + var xs = Array.Empty().ToAsyncEnumerable().MinByWithTiesAsync(x => x / 2); + + await AssertThrowsAsync(xs.AsTask()); + } + + [Fact] + public async Task MinByWithTies3Async() + { + var ex = new Exception("Bang!"); + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinByWithTiesAsync(x => { if (x == 3) throw ex; return x; }); + + await AssertThrowsAsync(xs, ex); + } + + [Fact] + public async Task MinByWithTies4Async() + { + var ex = new Exception("Bang!"); + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().MinByWithTiesAsync(x => { if (x == 4) throw ex; return x; }); + + await AssertThrowsAsync(xs, ex); + } + + [Fact] + public async Task MinByWithTies5Async() + { + var ex = new Exception("Bang!"); + var xs = new[] { 3, 5, 7, 6, 4, 2 }.ToAsyncEnumerable().Concat(Throw(ex)).MinByWithTiesAsync(x => x, Comparer.Default); + + await AssertThrowsAsync(xs, ex); + } + } +} diff --git a/Ix.NET/Source/System.Interactive.Async/System.Interactive.Async.csproj b/Ix.NET/Source/System.Interactive.Async/System.Interactive.Async.csproj index 0938bbdecb..13345a6089 100644 --- a/Ix.NET/Source/System.Interactive.Async/System.Interactive.Async.csproj +++ b/Ix.NET/Source/System.Interactive.Async/System.Interactive.Async.csproj @@ -33,6 +33,30 @@ + + + + + + + + + + $(NoWarn);NU5128;NU5131 + + diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs index 55694cc190..327280cdca 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Distinct.cs @@ -20,6 +20,7 @@ public static partial class AsyncEnumerableEx /// An async-enumerable sequence only containing the distinct elements, based on a computed key value, from the source sequence. /// or is null. /// Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + [Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and the functionality of selector-based overloads of Distinct now exists as DistinctBy.")] public static IAsyncEnumerable Distinct(this IAsyncEnumerable source, Func keySelector) { if (source == null) @@ -41,6 +42,7 @@ public static IAsyncEnumerable Distinct(this IAsyncEnume /// An async-enumerable sequence only containing the distinct elements, based on a computed key value, from the source sequence. /// or or is null. /// Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + [Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and the functionality of selector-based overloads of Distinct now exists as DistinctBy.")] public static IAsyncEnumerable Distinct(this IAsyncEnumerable source, Func keySelector, IEqualityComparer? comparer) { if (source == null) @@ -61,6 +63,7 @@ public static IAsyncEnumerable Distinct(this IAsyncEnume /// An async-enumerable sequence only containing the distinct elements, based on a computed key value, from the source sequence. /// or is null. /// Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + [Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and the functionality of selector-based overloads of Distinct now exists as DistinctBy.")] public static IAsyncEnumerable Distinct(this IAsyncEnumerable source, Func> keySelector) { if (source == null) @@ -82,6 +85,7 @@ public static IAsyncEnumerable Distinct(this IAsyncEnume /// An async-enumerable sequence only containing the distinct elements, based on a computed key value, from the source sequence. /// or is null. /// Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + [Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and the functionality of selector-based overloads of Distinct now exists as DistinctBy.")] public static IAsyncEnumerable Distinct(this IAsyncEnumerable source, Func> keySelector) { if (source == null) @@ -104,6 +108,7 @@ public static IAsyncEnumerable Distinct(this IAsyncEnume /// An async-enumerable sequence only containing the distinct elements, based on a computed key value, from the source sequence. /// or or is null. /// Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + [Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and the functionality of selector-based overloads of Distinct now exists as DistinctBy.")] public static IAsyncEnumerable Distinct(this IAsyncEnumerable source, Func> keySelector, IEqualityComparer? comparer) { if (source == null) @@ -126,6 +131,7 @@ public static IAsyncEnumerable Distinct(this IAsyncEnume /// An async-enumerable sequence only containing the distinct elements, based on a computed key value, from the source sequence. /// or or is null. /// Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + [Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and the functionality of selector-based overloads of Distinct now exists as DistinctBy.")] public static IAsyncEnumerable Distinct(this IAsyncEnumerable source, Func> keySelector, IEqualityComparer? comparer) { if (source == null) diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs index a91e708abc..191939883b 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Max.cs @@ -10,6 +10,7 @@ namespace System.Linq { public static partial class AsyncEnumerableEx { +#if !REFERENCE_ASSEMBLY /// /// Returns the maximum value in an async-enumerable sequence according to the specified comparer. /// @@ -51,5 +52,6 @@ static async ValueTask Core(IAsyncEnumerable source, IComparer return max; } } +#endif } } diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs index 6085624662..ee4f656a85 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxBy.cs @@ -10,6 +10,7 @@ namespace System.Linq { public static partial class AsyncEnumerableEx { +#if !REFERENCE_ASSEMBLY /// /// Returns the elements in an async-enumerable sequence with the maximum key value. /// @@ -164,6 +165,8 @@ private static ValueTask> MaxByCore(IAsyncEnumerab return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken); } +#endif + #endif } } diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxByWithTies.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxByWithTies.cs new file mode 100644 index 0000000000..bac3d2f758 --- /dev/null +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MaxByWithTies.cs @@ -0,0 +1,169 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT License. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Linq +{ + public static partial class AsyncEnumerableEx + { + /// + /// Returns the elements in an async-enumerable sequence with the maximum key value. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the maximum elements for. + /// Key selector function. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a maximum key value. + /// or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MaxByWithTiesAsync(this IAsyncEnumerable source, Func keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MaxByWithTiesCore(source, keySelector, comparer: null, cancellationToken); + } + + /// + /// Returns the elements in an async-enumerable sequence with the maximum key value according to the specified comparer. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the maximum elements for. + /// Key selector function. + /// Comparer used to compare key values. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a maximum key value. + /// or or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MaxByWithTiesAsync(this IAsyncEnumerable source, Func keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MaxByWithTiesCore(source, keySelector, comparer, cancellationToken); + } + + /// + /// Returns the elements in an async-enumerable sequence with the maximum key value. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the maximum elements for. + /// Key selector function returning a key possibly asynchronously. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a maximum key value. + /// or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MaxByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MaxByWithTiesCore(source, keySelector, comparer: null, cancellationToken); + } + +#if !NO_DEEP_CANCELLATION + /// + /// Returns the elements in an async-enumerable sequence with the maximum key value. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the maximum elements for. + /// Key selector function returning a key possibly asynchronously and supporting cancellation. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a maximum key value. + /// or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MaxByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MaxByWithTiesCore(source, keySelector, comparer: null, cancellationToken); + } +#endif + + /// + /// Returns the elements in an async-enumerable sequence with the maximum key value according to the specified comparer. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the maximum elements for. + /// Key selector function returning a key possibly asynchronously. + /// Comparer used to compare key values. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a maximum key value. + /// or or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MaxByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MaxByWithTiesCore(source, keySelector, comparer, cancellationToken); + } + +#if !NO_DEEP_CANCELLATION + /// + /// Returns the elements in an async-enumerable sequence with the maximum key value according to the specified comparer. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the maximum elements for. + /// Key selector function returning a key possibly asynchronously and supporting cancellation. + /// Comparer used to compare key values. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a maximum key value. + /// or or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MaxByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MaxByWithTiesCore(source, keySelector, comparer, cancellationToken); + } +#endif + + private static ValueTask> MaxByWithTiesCore(IAsyncEnumerable source, Func keySelector, IComparer? comparer, CancellationToken cancellationToken) + { + comparer ??= Comparer.Default; + + return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken); + } + + private static ValueTask> MaxByWithTiesCore(IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken) + { + comparer ??= Comparer.Default; + + return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken); + } + +#if !NO_DEEP_CANCELLATION + private static ValueTask> MaxByWithTiesCore(IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken) + { + comparer ??= Comparer.Default; + + return ExtremaBy(source, keySelector, (key, minValue) => comparer.Compare(key, minValue), cancellationToken); + } +#endif + } +} diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs index 53b70b3f5d..9d81755483 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/Min.cs @@ -10,6 +10,7 @@ namespace System.Linq { public static partial class AsyncEnumerableEx { +#if !REFERENCE_ASSEMBLY /// /// Returns the minimum element in an async-enumerable sequence according to the specified comparer. /// @@ -51,5 +52,6 @@ static async ValueTask Core(IAsyncEnumerable source, IComparer return min; } } +#endif } } diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs index 1983e05da5..80e580d680 100644 --- a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinBy.cs @@ -10,6 +10,7 @@ namespace System.Linq { public static partial class AsyncEnumerableEx { +#if !REFERENCE_ASSEMBLY /// /// Returns the elements in an async-enumerable sequence with the minimum key value. /// @@ -166,111 +167,6 @@ private static ValueTask> MinByCore(IAsyncEnumerab } #endif - private static async ValueTask> ExtremaBy(IAsyncEnumerable source, Func keySelector, Func compare, CancellationToken cancellationToken) - { - var result = new List(); - - await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) - { - if (!await e.MoveNextAsync()) - throw Error.NoElements(); - - var current = e.Current; - var resKey = keySelector(current); - result.Add(current); - - while (await e.MoveNextAsync()) - { - var cur = e.Current; - var key = keySelector(cur); - - var cmp = compare(key, resKey); - - if (cmp == 0) - { - result.Add(cur); - } - else if (cmp > 0) - { - result = [cur]; - resKey = key; - } - } - } - - return result; - } - - private static async ValueTask> ExtremaBy(IAsyncEnumerable source, Func> keySelector, Func compare, CancellationToken cancellationToken) - { - var result = new List(); - - await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) - { - if (!await e.MoveNextAsync()) - throw Error.NoElements(); - - var current = e.Current; - var resKey = await keySelector(current).ConfigureAwait(false); - result.Add(current); - - while (await e.MoveNextAsync()) - { - var cur = e.Current; - var key = await keySelector(cur).ConfigureAwait(false); - - var cmp = compare(key, resKey); - - if (cmp == 0) - { - result.Add(cur); - } - else if (cmp > 0) - { - result = [cur]; - resKey = key; - } - } - } - - return result; - } - -#if !NO_DEEP_CANCELLATION - private static async ValueTask> ExtremaBy(IAsyncEnumerable source, Func> keySelector, Func compare, CancellationToken cancellationToken) - { - var result = new List(); - - await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) - { - if (!await e.MoveNextAsync()) - throw Error.NoElements(); - - var current = e.Current; - var resKey = await keySelector(current, cancellationToken).ConfigureAwait(false); - result.Add(current); - - while (await e.MoveNextAsync()) - { - var cur = e.Current; - var key = await keySelector(cur, cancellationToken).ConfigureAwait(false); - - var cmp = compare(key, resKey); - - if (cmp == 0) - { - result.Add(cur); - } - else if (cmp > 0) - { - result = [cur]; - resKey = key; - } - } - } - - return result; - } #endif } } diff --git a/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinByWithTies.cs b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinByWithTies.cs new file mode 100644 index 0000000000..1e4af9b0e7 --- /dev/null +++ b/Ix.NET/Source/System.Interactive.Async/System/Linq/Operators/MinByWithTies.cs @@ -0,0 +1,276 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT License. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Linq +{ + public static partial class AsyncEnumerableEx + { + /// + /// Returns the elements in an async-enumerable sequence with the minimum key value. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the minimum elements for. + /// Key selector function. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a minimum key value. + /// or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MinByWithTiesAsync(this IAsyncEnumerable source, Func keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MinByWithTiesCore(source, keySelector, comparer: null, cancellationToken); + } + + /// + /// Returns the elements in an async-enumerable sequence with the minimum key value according to the specified comparer. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the minimum elements for. + /// Key selector function. + /// Comparer used to compare key values. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a minimum key value. + /// or or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MinByWithTiesAsync(this IAsyncEnumerable source, Func keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MinByWithTiesCore(source, keySelector, comparer, cancellationToken); + } + + /// + /// Returns the elements in an async-enumerable sequence with the minimum key value. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the minimum elements for. + /// Key selector function returning a key possibly asynchronously. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a minimum key value. + /// or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MinByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MinByWithTiesCore(source, keySelector, comparer: null, cancellationToken); + } + +#if !NO_DEEP_CANCELLATION + /// + /// Returns the elements in an async-enumerable sequence with the minimum key value. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the minimum elements for. + /// Key selector function returning a key possibly asynchronously and supporting cancellation. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a minimum key value. + /// or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MinByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MinByWithTiesCore(source, keySelector, comparer: null, cancellationToken); + } +#endif + + /// + /// Returns the elements in an async-enumerable sequence with the minimum key value according to the specified comparer. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the minimum elements for. + /// Key selector function returning a key possibly asynchronously. + /// Comparer used to compare key values. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a minimum key value. + /// or or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MinByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MinByWithTiesCore(source, keySelector, comparer, cancellationToken); + } + +#if !NO_DEEP_CANCELLATION + /// + /// Returns the elements in an async-enumerable sequence with the minimum key value according to the specified comparer. + /// + /// The type of the elements in the source sequence. + /// The type of the key computed for each element in the source sequence. + /// An async-enumerable sequence to get the minimum elements for. + /// Key selector function returning a key possibly asynchronously and supporting cancellation. + /// Comparer used to compare key values. + /// The optional cancellation token to be used for cancelling the sequence at any time. + /// A ValueTask containing a list of zero or more elements that have a minimum key value. + /// or or is null. + /// The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior. + public static ValueTask> MinByWithTiesAsync(this IAsyncEnumerable source, Func> keySelector, IComparer comparer, CancellationToken cancellationToken = default) + { + if (source == null) + throw Error.ArgumentNull(nameof(source)); + if (keySelector == null) + throw Error.ArgumentNull(nameof(keySelector)); + + return MinByWithTiesCore(source, keySelector, comparer, cancellationToken); + } +#endif + + private static ValueTask> MinByWithTiesCore(IAsyncEnumerable source, Func keySelector, IComparer? comparer, CancellationToken cancellationToken) + { + comparer ??= Comparer.Default; + + return ExtremaBy(source, keySelector, (key, minValue) => -comparer.Compare(key, minValue), cancellationToken); + } + + private static ValueTask> MinByWithTiesCore(IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken) + { + comparer ??= Comparer.Default; + + return ExtremaBy(source, keySelector, (key, minValue) => -comparer.Compare(key, minValue), cancellationToken); + } + +#if !NO_DEEP_CANCELLATION + private static ValueTask> MinByWithTiesCore(IAsyncEnumerable source, Func> keySelector, IComparer? comparer, CancellationToken cancellationToken) + { + comparer ??= Comparer.Default; + + return ExtremaBy(source, keySelector, (key, minValue) => -comparer.Compare(key, minValue), cancellationToken); + } +#endif + + private static async ValueTask> ExtremaBy(IAsyncEnumerable source, Func keySelector, Func compare, CancellationToken cancellationToken) + { + var result = new List(); + + await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) + { + if (!await e.MoveNextAsync()) + throw Error.NoElements(); + + var current = e.Current; + var resKey = keySelector(current); + result.Add(current); + + while (await e.MoveNextAsync()) + { + var cur = e.Current; + var key = keySelector(cur); + + var cmp = compare(key, resKey); + + if (cmp == 0) + { + result.Add(cur); + } + else if (cmp > 0) + { + result = [cur]; + resKey = key; + } + } + } + + return result; + } + + private static async ValueTask> ExtremaBy(IAsyncEnumerable source, Func> keySelector, Func compare, CancellationToken cancellationToken) + { + var result = new List(); + + await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) + { + if (!await e.MoveNextAsync()) + throw Error.NoElements(); + + var current = e.Current; + var resKey = await keySelector(current).ConfigureAwait(false); + result.Add(current); + + while (await e.MoveNextAsync()) + { + var cur = e.Current; + var key = await keySelector(cur).ConfigureAwait(false); + + var cmp = compare(key, resKey); + + if (cmp == 0) + { + result.Add(cur); + } + else if (cmp > 0) + { + result = [cur]; + resKey = key; + } + } + } + + return result; + } + +#if !NO_DEEP_CANCELLATION + private static async ValueTask> ExtremaBy(IAsyncEnumerable source, Func> keySelector, Func compare, CancellationToken cancellationToken) + { + var result = new List(); + + await using (var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false)) + { + if (!await e.MoveNextAsync()) + throw Error.NoElements(); + + var current = e.Current; + var resKey = await keySelector(current, cancellationToken).ConfigureAwait(false); + result.Add(current); + + while (await e.MoveNextAsync()) + { + var cur = e.Current; + var key = await keySelector(cur, cancellationToken).ConfigureAwait(false); + + var cmp = compare(key, resKey); + + if (cmp == 0) + { + result.Add(cur); + } + else if (cmp > 0) + { + result = [cur]; + resKey = key; + } + } + } + + return result; + } +#endif + } +} diff --git a/Ix.NET/Source/System.Interactive.Providers/System.Interactive.Providers.csproj b/Ix.NET/Source/System.Interactive.Providers/System.Interactive.Providers.csproj index aa5d3b7e68..48e0ec4579 100644 --- a/Ix.NET/Source/System.Interactive.Providers/System.Interactive.Providers.csproj +++ b/Ix.NET/Source/System.Interactive.Providers/System.Interactive.Providers.csproj @@ -21,7 +21,7 @@ See ../../Documentation/adr/0001-Ix-Ref-Assembly-Mismatches.md --> - + - + - + diff --git a/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs b/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs index e5c3ce6824..51e3b3abf9 100644 --- a/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs +++ b/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsync.verified.cs @@ -57,11 +57,29 @@ public static System.Collections.Generic.IAsyncEnumerable Concat Defer(System.Func> factory) { } public static System.Collections.Generic.IAsyncEnumerable Defer(System.Func>> factory) { } public static System.Collections.Generic.IAsyncEnumerable Defer(System.Func>> factory) { } + [System.Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and" + + " the functionality of selector-based overloads of Distinct now exists as Distinc" + + "tBy.")] public static System.Collections.Generic.IAsyncEnumerable Distinct(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector) { } + [System.Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and" + + " the functionality of selector-based overloads of Distinct now exists as Distinc" + + "tBy.")] public static System.Collections.Generic.IAsyncEnumerable Distinct(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector) { } + [System.Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and" + + " the functionality of selector-based overloads of Distinct now exists as Distinc" + + "tBy.")] public static System.Collections.Generic.IAsyncEnumerable Distinct(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector) { } + [System.Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and" + + " the functionality of selector-based overloads of Distinct now exists as Distinc" + + "tBy.")] public static System.Collections.Generic.IAsyncEnumerable Distinct(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IEqualityComparer? comparer) { } + [System.Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and" + + " the functionality of selector-based overloads of Distinct now exists as Distinc" + + "tBy.")] public static System.Collections.Generic.IAsyncEnumerable Distinct(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Collections.Generic.IEqualityComparer? comparer) { } + [System.Obsolete("Use DistinctBy. IAsyncEnumerable LINQ is now in System.Linq.AsyncEnumerable, and" + + " the functionality of selector-based overloads of Distinct now exists as Distinc" + + "tBy.")] public static System.Collections.Generic.IAsyncEnumerable Distinct(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IEqualityComparer? comparer) { } public static System.Collections.Generic.IAsyncEnumerable DistinctUntilChanged(this System.Collections.Generic.IAsyncEnumerable source) { } public static System.Collections.Generic.IAsyncEnumerable DistinctUntilChanged(this System.Collections.Generic.IAsyncEnumerable source, System.Collections.Generic.IEqualityComparer? comparer) { } @@ -99,6 +117,12 @@ public static System.Threading.Tasks.ValueTask MaxAsync(this S public static System.Threading.Tasks.ValueTask> MaxByAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MaxByAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MaxByAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Collections.Generic.IAsyncEnumerable Merge(this System.Collections.Generic.IAsyncEnumerable> sources) { } public static System.Collections.Generic.IAsyncEnumerable Merge(params System.Collections.Generic.IAsyncEnumerable[] sources) { } public static System.Collections.Generic.IAsyncEnumerable Merge(this System.Collections.Generic.IEnumerable> sources) { } @@ -109,6 +133,12 @@ public static System.Threading.Tasks.ValueTask MinAsync(this S public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Collections.Generic.IAsyncEnumerable source, System.Func> keySelector, System.Collections.Generic.IComparer comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Collections.Generic.IAsyncEnumerable Never() { } public static System.Collections.Generic.IAsyncEnumerable OnErrorResumeNext(params System.Collections.Generic.IAsyncEnumerable[] sources) { } public static System.Collections.Generic.IAsyncEnumerable OnErrorResumeNext(this System.Collections.Generic.IEnumerable> sources) { } diff --git a/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsyncProviders.verified.cs b/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsyncProviders.verified.cs index 6fbdaa9968..e96f961716 100644 --- a/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsyncProviders.verified.cs +++ b/Ix.NET/Source/Tests.System.Interactive.ApiApprovals/Api/ApiApprovalTests.SystemInteractiveAsyncProviders.verified.cs @@ -8,6 +8,37 @@ namespace System.Linq public static class AsyncQueryableEx { public static System.Linq.IAsyncQueryable Amb(this System.Linq.IAsyncQueryable first, System.Collections.Generic.IAsyncEnumerable second) { } + public static System.Linq.IAsyncQueryable AsAsyncEnumerable(this System.Linq.IAsyncQueryable source) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask AverageAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> selector, System.Threading.CancellationToken cancellationToken = default) { } public static System.Linq.IAsyncQueryable> Buffer(this System.Linq.IAsyncQueryable source, int count) { } public static System.Linq.IAsyncQueryable> Buffer(this System.Linq.IAsyncQueryable source, int count, int skip) { } public static System.Linq.IAsyncQueryable Catch(this System.Linq.IAsyncQueryable first, System.Collections.Generic.IAsyncEnumerable second) { } @@ -56,6 +87,12 @@ public static System.Threading.Tasks.ValueTask MaxAsync(this S public static System.Threading.Tasks.ValueTask> MaxByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MaxByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MaxByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MaxByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Linq.IAsyncQueryable Merge(this System.Linq.IAsyncQueryable> sources) { } public static System.Threading.Tasks.ValueTask MinAsync(this System.Linq.IAsyncQueryable source, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Threading.CancellationToken cancellationToken = default) { } @@ -64,6 +101,12 @@ public static System.Threading.Tasks.ValueTask MinAsync(this S public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Threading.Tasks.ValueTask> MinByAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } + public static System.Threading.Tasks.ValueTask> MinByWithTiesAsync(this System.Linq.IAsyncQueryable source, System.Linq.Expressions.Expression>> keySelector, System.Collections.Generic.IComparer? comparer, System.Threading.CancellationToken cancellationToken = default) { } public static System.Linq.IAsyncQueryable OnErrorResumeNext(this System.Linq.IAsyncQueryable first, System.Collections.Generic.IAsyncEnumerable second) { } public static System.Linq.IAsyncQueryable Repeat(this System.Linq.IAsyncQueryable source) { } public static System.Linq.IAsyncQueryable Repeat(this System.Linq.IAsyncQueryable source, int count) { } diff --git a/Ix.NET/Source/refs/System.Interactive.Async/System.Interactive.Async.csproj b/Ix.NET/Source/refs/System.Interactive.Async/System.Interactive.Async.csproj new file mode 100644 index 0000000000..cc8c6902cd --- /dev/null +++ b/Ix.NET/Source/refs/System.Interactive.Async/System.Interactive.Async.csproj @@ -0,0 +1,44 @@ + + + + true + + Interactive Extensions Async Library used to express queries over asynchronous enumerable sequences. + Interactive Extensions - Async Library + Microsoft + + + net48;netstandard2.1;net6.0;net10.0 + Ix;Interactive;Extensions;Enumerable;Asynchronous + + + + + + + + + + + + + + + + + + + + +