Skip to content

Commit cf5da2b

Browse files
committed
Fixed IsFisrt/IsLast in EnumerableExtensions class to handle empty IList<T> collection
1 parent 35f9405 commit cf5da2b

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

Main/src/Collections/Enumerable/EnumerableExtensions.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ public static bool IsFirst<TSource>(
477477
// Fast path
478478
// ReSharper disable once CollectionNeverUpdated.Local
479479
if (source is IList<TSource> list)
480-
return comparer.Equals(item, list[0]);
480+
return list.Count != 0 && comparer.Equals(item, list[0]);
481481

482482
foreach (var current in source)
483483
return comparer.Equals(item, current);
@@ -522,7 +522,10 @@ public static bool IsLast<TSource>(
522522
// Fast path
523523
// ReSharper disable once CollectionNeverUpdated.Local
524524
if (source is IList<TSource> list)
525-
return comparer.Equals(item, list[list.Count - 1]);
525+
{
526+
var count = list.Count;
527+
return count != 0 && comparer.Equals(item, list[count - 1]);
528+
}
526529

527530
using (var en = source.GetEnumerator())
528531
if (en.MoveNext())

Main/tests/Collections/Enumerable/EnumerableExtensionTests.cs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using System.Linq;
34

45
using CodeJam.Strings;
@@ -32,6 +33,7 @@ public string Prepend(string[] input, string[] prepend)
3233
=> input.Prepend(prepend).Join(", ");
3334

3435
[Test]
36+
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
3537
public void IsFirst()
3638
{
3739
var src = new[] { "a", "b", "c" };
@@ -46,17 +48,37 @@ public void IsFirst()
4648

4749
// Slow path
4850
var enSrc = src.Select(i => i);
49-
// ReSharper disable PossibleMultipleEnumeration
5051
Assert.IsTrue(enSrc.IsFirst("a"), "#A06");
5152
Assert.IsFalse(enSrc.IsFirst("b"), "#A07");
5253

5354
Assert.IsTrue(enSrc.IsFirst("a", null), "#A08");
5455
Assert.IsFalse(enSrc.IsFirst("A", null), "#A09");
5556
Assert.IsTrue(enSrc.IsFirst("A", StringComparer.OrdinalIgnoreCase), "#A10");
56-
// ReSharper restore PossibleMultipleEnumeration
5757
}
5858

5959
[Test]
60+
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
61+
public void IsFirstForEmptyCollections()
62+
{
63+
var src = new string[0];
64+
65+
// Fast path
66+
Assert.IsFalse(src.IsFirst("a"), "#A01");
67+
Assert.IsFalse(src.IsFirst("b"), "#A02");
68+
Assert.IsFalse(src.IsFirst("A", null), "#A03");
69+
Assert.IsFalse(src.IsFirst("A", StringComparer.OrdinalIgnoreCase), "#A04");
70+
71+
// Slow path
72+
var enSrc = src.Select(i => i);
73+
Assert.IsFalse(enSrc.IsFirst("a"), "#A05");
74+
Assert.IsFalse(enSrc.IsFirst("b"), "#A06");
75+
76+
Assert.IsFalse(enSrc.IsFirst("a", null), "#A07");
77+
Assert.IsFalse(enSrc.IsFirst("A", StringComparer.OrdinalIgnoreCase), "#A08");
78+
}
79+
80+
[Test]
81+
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
6082
public void IsLast()
6183
{
6284
var src = new[] { "a", "b", "c" };
@@ -71,14 +93,32 @@ public void IsLast()
7193

7294
// Slow path
7395
var enSrc = src.Select(i => i);
74-
// ReSharper disable PossibleMultipleEnumeration
7596
Assert.IsTrue(enSrc.IsLast("c"), "#A06");
7697
Assert.IsFalse(enSrc.IsLast("b"), "#A07");
7798

7899
Assert.IsTrue(enSrc.IsLast("c", null), "#A08");
79100
Assert.IsFalse(enSrc.IsLast("C", null), "#A09");
80101
Assert.IsTrue(enSrc.IsLast("C", StringComparer.OrdinalIgnoreCase), "#A10");
81-
// ReSharper restore PossibleMultipleEnumeration
102+
}
103+
104+
[Test]
105+
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
106+
public void IsLastForEmptyCollections()
107+
{
108+
var src = new string[0];
109+
110+
// Fast path
111+
Assert.IsFalse(src.IsLast("c"), "#A01");
112+
Assert.IsFalse(src.IsLast("b"), "#A02");
113+
Assert.IsFalse(src.IsLast("c", null), "#A03");
114+
Assert.IsFalse(src.IsLast("C", StringComparer.OrdinalIgnoreCase), "#A04");
115+
116+
// Slow path
117+
var enSrc = src.Select(i => i);
118+
Assert.IsFalse(enSrc.IsLast("c"), "#A05");
119+
Assert.IsFalse(enSrc.IsLast("b"), "#A06");
120+
Assert.IsFalse(enSrc.IsLast("C", null), "#A07");
121+
Assert.IsFalse(enSrc.IsLast("C", StringComparer.OrdinalIgnoreCase), "#A08");
82122
}
83123
}
84124
}

0 commit comments

Comments
 (0)