Browse Source

Fixing ElementAtOrDefault behavior.

Bart De Smet 7 years ago
parent
commit
c4cf6ed51f

+ 7 - 3
Ix.NET/Source/System.Linq.Async.Tests/System/Linq/Operators/ElementAtOrDefault.cs

@@ -17,10 +17,7 @@ namespace Tests
         public async Task ElementAtOrDefault_Null()
         {
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ElementAtOrDefault<int>(default, 0));
-            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAtOrDefault<int>(Return42, -1));
-
             await Assert.ThrowsAsync<ArgumentNullException>(() => AsyncEnumerable.ElementAtOrDefault<int>(default, 0, CancellationToken.None));
-            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => AsyncEnumerable.ElementAtOrDefault<int>(Return42, -1, CancellationToken.None));
         }
 
         [Fact]
@@ -60,6 +57,13 @@ namespace Tests
 
         [Fact]
         public void ElementAtOrDefault6()
+        {
+            var res = Return42.ElementAtOrDefault(-1);
+            Assert.Equal(0, res.Result);
+        }
+
+        [Fact]
+        public void ElementAtOrDefault7()
         {
             var ex = new Exception("Bang!");
             var res = Throw<int>(ex).ElementAtOrDefault(15);

+ 25 - 25
Ix.NET/Source/System.Linq.Async/System/Linq/Operators/ElementAtOrDefault.cs

@@ -14,8 +14,6 @@ namespace System.Linq
         {
             if (source == null)
                 throw Error.ArgumentNull(nameof(source));
-            if (index < 0)
-                throw Error.ArgumentOutOfRange(nameof(index));
 
             return ElementAtOrDefaultCore(source, index, CancellationToken.None);
         }
@@ -24,22 +22,13 @@ namespace System.Linq
         {
             if (source == null)
                 throw Error.ArgumentNull(nameof(source));
-            if (index < 0)
-                throw Error.ArgumentOutOfRange(nameof(index));
 
             return ElementAtOrDefaultCore(source, index, cancellationToken);
         }
 
         private static async Task<TSource> ElementAtOrDefaultCore<TSource>(IAsyncEnumerable<TSource> source, int index, CancellationToken cancellationToken)
         {
-            if (source is IList<TSource> list)
-            {
-                if (index < list.Count)
-                {
-                    return list[index];
-                }
-            }
-            else if (source is IAsyncPartition<TSource> p)
+            if (source is IAsyncPartition<TSource> p)
             {
                 var first = await p.TryGetElementAsync(index, cancellationToken).ConfigureAwait(false);
 
@@ -48,25 +37,36 @@ namespace System.Linq
                     return first.Value;
                 }
             }
-            else
-            {
-                var e = source.GetAsyncEnumerator(cancellationToken);
 
-                try
+            if (index >= 0)
+            {
+                if (source is IList<TSource> list)
                 {
-                    while (await e.MoveNextAsync().ConfigureAwait(false))
+                    if (index < list.Count)
                     {
-                        if (index == 0)
-                        {
-                            return e.Current;
-                        }
-
-                        index--;
+                        return list[index];
                     }
                 }
-                finally
+                else
                 {
-                    await e.DisposeAsync().ConfigureAwait(false);
+                    var e = source.GetAsyncEnumerator(cancellationToken);
+
+                    try
+                    {
+                        while (await e.MoveNextAsync().ConfigureAwait(false))
+                        {
+                            if (index == 0)
+                            {
+                                return e.Current;
+                            }
+
+                            index--;
+                        }
+                    }
+                    finally
+                    {
+                        await e.DisposeAsync().ConfigureAwait(false);
+                    }
                 }
             }