Skip to content

Commit 030522b

Browse files
committed
Fix double evaluation of IEnumerable methods
The ToListOrNullIfEmpty() extension method called .Any() and .ToList() which both evaluate the IEnumerable. This caused funcs to be executed twice when applied to an IEnumerable<Func<>>. Closes #2101
1 parent dd40b6e commit 030522b

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

src/Nest/CommonAbstractions/Extensions/Extensions.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,11 @@ internal static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> handle
161161
foreach (T item in enumerable) handler(item);
162162
}
163163

164-
internal static List<T> ToListOrNullIfEmpty<T>(this IEnumerable<T> enumerable) =>
165-
enumerable.HasAny() ? enumerable.ToList() : null;
164+
internal static List<T> ToListOrNullIfEmpty<T>(this IEnumerable<T> enumerable)
165+
{
166+
var list = enumerable?.ToList();
167+
return list.HasAny() ? list : null;
168+
}
166169

167170
internal static void AddIfNotNull<T>(this IList<T> list, T item) where T : class
168171
{
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Elasticsearch.Net;
6+
using Nest;
7+
using FluentAssertions;
8+
using Tests.Framework;
9+
10+
namespace Tests.Reproduce
11+
{
12+
public class GithubIssue2101
13+
{
14+
15+
[U]
16+
public void BoolClausesShouldEvaluateOnlyOnce()
17+
{
18+
var must = 0;
19+
var mustNot = 0;
20+
var should = 0;
21+
var filter = 0;
22+
23+
new BoolQueryDescriptor<object>()
24+
.Must(m =>
25+
{
26+
must++;
27+
return m;
28+
})
29+
.MustNot(mn =>
30+
{
31+
mustNot++;
32+
return mn;
33+
})
34+
.Should(sh =>
35+
{
36+
should++;
37+
return sh;
38+
})
39+
.Filter(f =>
40+
{
41+
filter++;
42+
return f;
43+
});
44+
45+
filter.Should().Be(1);
46+
should.Should().Be(1);
47+
must.Should().Be(1);
48+
mustNot.Should().Be(1);
49+
}
50+
}
51+
}

src/Tests/Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@
570570
<Compile Include="Search\MultiSearch\MultiSearchApiTests.cs" />
571571
<Compile Include="Search\MultiSearch\MultiSearchInvalidApiTests.cs" />
572572
<Compile Include="QueryDsl\Verbatim\VerbatimAndStrictQueryUsageTests.cs" />
573+
<Compile Include="Reproduce\GithubIssue2101.cs" />
573574
<Compile Include="Search\Search\Rescoring\RescoreUsageTests.cs" />
574575
<Compile Include="XPack\Security\ClearCachedRealms\ClearCachedRealmsApiTests.cs" />
575576
<Compile Include="XPack\Security\ClearCachedRealms\ClearCachedRealmsUrlTests.cs" />

0 commit comments

Comments
 (0)