Browse Source

Inlining Max/Min code

Bart De Smet 7 years ago
parent
commit
e993d80482

+ 0 - 335
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.Generic.cs

@@ -1,335 +0,0 @@
-// 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 AsyncEnumerable
-    {
-        private static Task<TSource> MaxCore<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TSource>.Default;
-            if (default(TSource) == null)
-            {
-                return Core();
-
-                async Task<TSource> Core()
-                {
-                    var value = default(TSource);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = e.Current;
-                        }
-                        while (value == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = e.Current;
-                            if (x != null && comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TSource> Core()
-                {
-                    var value = default(TSource);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = e.Current;
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = e.Current;
-                            if (comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-
-        private static Task<TResult> MaxCore<TSource, TResult>(IAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TResult>.Default;
-            if (default(TResult) == null)
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = selector(e.Current);
-                        }
-                        while (value == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = selector(e.Current);
-                            if (x != null && comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = selector(e.Current);
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = selector(e.Current);
-                            if (comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-
-        private static Task<TResult> MaxCore<TSource, TResult>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TResult>> selector, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TResult>.Default;
-            if (default(TResult) == null)
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = await selector(e.Current).ConfigureAwait(false);
-                        }
-                        while (value == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current).ConfigureAwait(false);
-                            if (x != null && comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = await selector(e.Current).ConfigureAwait(false);
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current).ConfigureAwait(false);
-                            if (comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-
-#if !NO_DEEP_CANCELLATION
-        private static Task<TResult> MaxCore<TSource, TResult>(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TResult>> selector, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TResult>.Default;
-            if (default(TResult) == null)
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                        }
-                        while (value == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                            if (x != null && comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                            if (comparer.Compare(x, value) > 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-#endif
-    }
-}

+ 304 - 4
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Max.cs

@@ -15,7 +15,82 @@ namespace System.Linq
             if (source == null)
                 throw Error.ArgumentNull(nameof(source));
 
-            return MaxCore(source, cancellationToken);
+            var comparer = Comparer<TSource>.Default;
+            if (default(TSource) == null)
+            {
+                return Core();
+
+                async Task<TSource> Core()
+                {
+                    var value = default(TSource);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = e.Current;
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = e.Current;
+                            if (x != null && comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TSource> Core()
+                {
+                    var value = default(TSource);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = e.Current;
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = e.Current;
+                            if (comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 
         public static Task<TResult> MaxAsync<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken = default)
@@ -25,7 +100,82 @@ namespace System.Linq
             if (selector == null)
                 throw Error.ArgumentNull(nameof(selector));
 
-            return MaxCore(source, selector, cancellationToken);
+            var comparer = Comparer<TResult>.Default;
+            if (default(TResult) == null)
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = selector(e.Current);
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = selector(e.Current);
+                            if (x != null && comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = selector(e.Current);
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = selector(e.Current);
+                            if (comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 
         public static Task<TResult> MaxAsync<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TResult>> selector, CancellationToken cancellationToken = default)
@@ -35,7 +185,82 @@ namespace System.Linq
             if (selector == null)
                 throw Error.ArgumentNull(nameof(selector));
 
-            return MaxCore(source, selector, cancellationToken);
+            var comparer = Comparer<TResult>.Default;
+            if (default(TResult) == null)
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = await selector(e.Current).ConfigureAwait(false);
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current).ConfigureAwait(false);
+                            if (x != null && comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = await selector(e.Current).ConfigureAwait(false);
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current).ConfigureAwait(false);
+                            if (comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 
 #if !NO_DEEP_CANCELLATION
@@ -46,7 +271,82 @@ namespace System.Linq
             if (selector == null)
                 throw Error.ArgumentNull(nameof(selector));
 
-            return MaxCore(source, selector, cancellationToken);
+            var comparer = Comparer<TResult>.Default;
+            if (default(TResult) == null)
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                            if (x != null && comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                            if (comparer.Compare(x, value) > 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 #endif
     }

+ 0 - 335
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.Generic.cs

@@ -1,335 +0,0 @@
-// 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 AsyncEnumerable
-    {
-        private static Task<TSource> MinCore<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TSource>.Default;
-            if (default(TSource) == null)
-            {
-                return Core();
-
-                async Task<TSource> Core()
-                {
-                    var value = default(TSource);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = e.Current;
-                        }
-                        while (default(TSource) == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = e.Current;
-                            if (x != null && comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TSource> Core()
-                {
-                    var value = default(TSource);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = e.Current;
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = e.Current;
-                            if (comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-
-        private static Task<TResult> MinCore<TSource, TResult>(IAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TResult>.Default;
-            if (default(TResult) == null)
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = selector(e.Current);
-                        }
-                        while (default(TSource) == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = selector(e.Current);
-                            if (x != null && comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = selector(e.Current);
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = selector(e.Current);
-                            if (comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-
-        private static Task<TResult> MinCore<TSource, TResult>(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TResult>> selector, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TResult>.Default;
-            if (default(TResult) == null)
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = await selector(e.Current).ConfigureAwait(false);
-                        }
-                        while (default(TSource) == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current).ConfigureAwait(false);
-                            if (x != null && comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = await selector(e.Current).ConfigureAwait(false);
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current).ConfigureAwait(false);
-                            if (comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-
-#if !NO_DEEP_CANCELLATION
-        private static Task<TResult> MinCore<TSource, TResult>(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<TResult>> selector, CancellationToken cancellationToken)
-        {
-            var comparer = Comparer<TResult>.Default;
-            if (default(TResult) == null)
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        do
-                        {
-                            if (!await e.MoveNextAsync().ConfigureAwait(false))
-                            {
-                                return value;
-                            }
-
-                            value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                        }
-                        while (default(TSource) == null);
-
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                            if (x != null && comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-            else
-            {
-                return Core();
-
-                async Task<TResult> Core()
-                {
-                    var value = default(TResult);
-
-                    var e = source.GetAsyncEnumerator(cancellationToken);
-
-                    try
-                    {
-                        if (!await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            throw Error.NoElements();
-                        }
-
-                        value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                        while (await e.MoveNextAsync().ConfigureAwait(false))
-                        {
-                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
-                            if (comparer.Compare(x, value) < 0)
-                            {
-                                value = x;
-                            }
-                        }
-                    }
-                    finally
-                    {
-                        await e.DisposeAsync().ConfigureAwait(false);
-                    }
-
-                    return value;
-                }
-            }
-        }
-#endif
-    }
-}

+ 304 - 4
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/Min.cs

@@ -15,7 +15,82 @@ namespace System.Linq
             if (source == null)
                 throw Error.ArgumentNull(nameof(source));
 
-            return MinCore(source, cancellationToken);
+            var comparer = Comparer<TSource>.Default;
+            if (default(TSource) == null)
+            {
+                return Core();
+
+                async Task<TSource> Core()
+                {
+                    var value = default(TSource);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = e.Current;
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = e.Current;
+                            if (x != null && comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TSource> Core()
+                {
+                    var value = default(TSource);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = e.Current;
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = e.Current;
+                            if (comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 
         public static Task<TResult> MinAsync<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken = default)
@@ -25,7 +100,82 @@ namespace System.Linq
             if (selector == null)
                 throw Error.ArgumentNull(nameof(selector));
 
-            return MinCore(source, selector, cancellationToken);
+            var comparer = Comparer<TResult>.Default;
+            if (default(TResult) == null)
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = selector(e.Current);
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = selector(e.Current);
+                            if (x != null && comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = selector(e.Current);
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = selector(e.Current);
+                            if (comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 
         public static Task<TResult> MinAsync<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<TResult>> selector, CancellationToken cancellationToken = default)
@@ -35,7 +185,82 @@ namespace System.Linq
             if (selector == null)
                 throw Error.ArgumentNull(nameof(selector));
 
-            return MinCore(source, selector, cancellationToken);
+            var comparer = Comparer<TResult>.Default;
+            if (default(TResult) == null)
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = await selector(e.Current).ConfigureAwait(false);
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current).ConfigureAwait(false);
+                            if (x != null && comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = await selector(e.Current).ConfigureAwait(false);
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current).ConfigureAwait(false);
+                            if (comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 
 #if !NO_DEEP_CANCELLATION
@@ -46,7 +271,82 @@ namespace System.Linq
             if (selector == null)
                 throw Error.ArgumentNull(nameof(selector));
 
-            return MinCore(source, selector, cancellationToken);
+            var comparer = Comparer<TResult>.Default;
+            if (default(TResult) == null)
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        do
+                        {
+                            if (!await e.MoveNextAsync().ConfigureAwait(false))
+                            {
+                                return value;
+                            }
+
+                            value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                        }
+                        while (value == null);
+
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                            if (x != null && comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
+            else
+            {
+                return Core();
+
+                async Task<TResult> Core()
+                {
+                    var value = default(TResult);
+
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        if (!await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            throw Error.NoElements();
+                        }
+
+                        value = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            var x = await selector(e.Current, cancellationToken).ConfigureAwait(false);
+                            if (comparer.Compare(x, value) < 0)
+                            {
+                                value = x;
+                            }
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
+
+                    return value;
+                }
+            }
         }
 #endif
     }