Skip to content

Commit 82d9851

Browse files
committed
Swapping uses of Linq .First() for more performant IList.First() method
1 parent e6dad17 commit 82d9851

File tree

10 files changed

+41
-20
lines changed

10 files changed

+41
-20
lines changed

AgileMapper/Extensions/EnumerableExtensions.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ public static void AddUnlessNullOrEmpty(this ICollection<Expression> items, Expr
1616
}
1717
}
1818

19+
[DebuggerStepThrough]
20+
public static T First<T>(this IList<T> items) => items[0];
21+
22+
public static T First<T>(this IList<T> items, Func<T, bool> predicate)
23+
{
24+
for (int i = 0, n = items.Count; i < n; i++)
25+
{
26+
var item = items[i];
27+
28+
if (predicate.Invoke(item))
29+
{
30+
return item;
31+
}
32+
}
33+
34+
throw new InvalidOperationException("Sequence contains no matching element");
35+
}
36+
37+
[DebuggerStepThrough]
38+
public static T Last<T>(this IList<T> items) => items[items.Count - 1];
39+
1940
[DebuggerStepThrough]
2041
public static bool Any<T>(this ICollection<T> items) => items.Count > 0;
2142

@@ -41,7 +62,7 @@ public static bool None<T>(this IEnumerable<T> items, Func<T, bool> predicate)
4162
[DebuggerStepThrough]
4263
public static bool HasOne<T>(this ICollection<T> items) => items.Count == 1;
4364

44-
public static Expression ReverseChain<T>(this ICollection<T> items)
65+
public static Expression ReverseChain<T>(this IList<T> items)
4566
where T : IConditionallyChainable
4667
{
4768
return ReverseChain(
@@ -66,27 +87,27 @@ private static Expression AddPreConditionIfNecessary(IConditionallyChainable ite
6687
}
6788

6889
public static Expression ReverseChain<TItem>(
69-
this ICollection<TItem> items,
90+
this IList<TItem> items,
7091
Func<TItem, Expression> seedValueFactory,
7192
Func<Expression, TItem, Expression> itemValueFactory)
7293
{
7394
return Chain(items, i => i.Last(), seedValueFactory, itemValueFactory, i => i.Reverse());
7495
}
7596

7697
public static Expression Chain<TItem>(
77-
this ICollection<TItem> items,
98+
this IList<TItem> items,
7899
Func<TItem, Expression> seedValueFactory,
79100
Func<Expression, TItem, Expression> itemValueFactory)
80101
{
81102
return Chain(items, i => i.First(), seedValueFactory, itemValueFactory, i => i);
82103
}
83104

84105
private static Expression Chain<TItem>(
85-
ICollection<TItem> items,
86-
Func<ICollection<TItem>, TItem> seedFactory,
106+
IList<TItem> items,
107+
Func<IList<TItem>, TItem> seedFactory,
87108
Func<TItem, Expression> seedValueFactory,
88109
Func<Expression, TItem, Expression> itemValueFactory,
89-
Func<ICollection<TItem>, IEnumerable<TItem>> initialOperation)
110+
Func<IList<TItem>, IEnumerable<TItem>> initialOperation)
90111
{
91112
if (items.None())
92113
{

AgileMapper/Extensions/ExpressionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static ConstantExpression ToConstantExpression<TItem>(this TItem item, Ty
4343
[DebuggerStepThrough]
4444
public static DefaultExpression ToDefaultExpression(this Type type) => Expression.Default(type);
4545

46-
public static Expression AndTogether(this ICollection<Expression> expressions)
46+
public static Expression AndTogether(this IList<Expression> expressions)
4747
{
4848
if (expressions.None())
4949
{

AgileMapper/MappingRuleSetCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace AgileObjects.AgileMapper
22
{
33
using System.Collections.Generic;
4-
using System.Linq;
4+
using Extensions;
55
using Members.Population;
66
using ObjectPopulation;
77
using ObjectPopulation.Enumerables;

AgileMapper/Members/MemberFinder.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
internal class MemberFinder
1212
{
1313
private readonly ICache<TypeKey, Member> _idMemberCache;
14-
private readonly ICache<TypeKey, IEnumerable<Member>> _membersCache;
14+
private readonly ICache<TypeKey, IList<Member>> _membersCache;
1515

1616
public MemberFinder()
1717
{
1818
_idMemberCache = GlobalContext.Instance.Cache.CreateScoped<TypeKey, Member>();
19-
_membersCache = GlobalContext.Instance.Cache.CreateScoped<TypeKey, IEnumerable<Member>>();
19+
_membersCache = GlobalContext.Instance.Cache.CreateScoped<TypeKey, IList<Member>>();
2020
}
2121

2222
public Member GetIdentifierOrNull(TypeKey typeIdKey)
@@ -29,7 +29,7 @@ public Member GetIdentifierOrNull(TypeKey typeIdKey)
2929
});
3030
}
3131

32-
public IEnumerable<Member> GetSourceMembers(Type sourceType)
32+
public IList<Member> GetSourceMembers(Type sourceType)
3333
{
3434
return _membersCache.GetOrAdd(TypeKey.ForSourceMembers(sourceType), key =>
3535
{
@@ -46,7 +46,7 @@ public IEnumerable<Member> GetSourceMembers(Type sourceType)
4646
});
4747
}
4848

49-
public IEnumerable<Member> GetTargetMembers(Type targetType)
49+
public IList<Member> GetTargetMembers(Type targetType)
5050
{
5151
return _membersCache.GetOrAdd(TypeKey.ForTargetMembers(targetType), key =>
5252
{
@@ -158,7 +158,7 @@ private static bool OnlyCallableSetters(MethodInfo method)
158158

159159
#endregion
160160

161-
private static IEnumerable<Member> GetMembers(params IEnumerable<Member>[] members)
161+
private static IList<Member> GetMembers(params IEnumerable<Member>[] members)
162162
{
163163
var allMembers = members
164164
.SelectMany(m => m)

AgileMapper/ObjectPopulation/ComplexTypes/ComplexTypeConstructionFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ private class Construction : IConditionallyChainable
233233
private readonly Expression _construction;
234234
private readonly ParameterExpression _mappingDataObject;
235235

236-
public Construction(ICollection<Construction> constructions, ConstructionKey key)
236+
public Construction(IList<Construction> constructions, ConstructionKey key)
237237
: this(constructions.ReverseChain())
238238
{
239239
UsesMappingDataObjectParameter = constructions.Any(c => c.UsesMappingDataObjectParameter);

AgileMapper/ObjectPopulation/ComplexTypes/ComplexTypeMappingExpressionFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ private static Expression GetPopulationCallbackOrNull(
246246
}
247247

248248
private static void CreateSourceMemberTypeTesterIfRequired(
249-
ICollection<Expression> typeTests,
249+
IList<Expression> typeTests,
250250
IObjectMappingData mappingData)
251251
{
252252
if (typeTests.None())

AgileMapper/ObjectPopulation/ObjectMapper.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
namespace AgileObjects.AgileMapper.ObjectPopulation
22
{
33
using System;
4-
using System.Linq;
54
using System.Linq.Expressions;
65
#if NET_STANDARD
76
using System.Reflection;
@@ -48,7 +47,7 @@ private ICache<ObjectMapperKeyBase, IObjectMapperFunc> CreateRecursionMapperFunc
4847
foreach (var mappingLambdaAndKey in MapperData.RequiredMapperFuncsByKey)
4948
{
5049
var mappingLambda = mappingLambdaAndKey.Value;
51-
var mappingDataObject = mappingLambda.Parameters.First();
50+
var mappingDataObject = mappingLambda.Parameters[0];
5251
var mappingDataTypes = mappingDataObject.Type.GetGenericArguments();
5352

5453
var typesKey = new SourceAndTargetTypesKey(mappingDataTypes[0], mappingDataTypes[1]);

AgileMapper/ObjectPopulation/ObjectMapperData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ public static ObjectMapperData For<TSource, TTarget>(IObjectMappingData mappingD
330330

331331
public ObjectMapperData DeclaredTypeMapperData { get; }
332332

333-
public ICollection<ObjectMapperData> ChildMapperDatas => _childMapperDatas;
333+
public IList<ObjectMapperData> ChildMapperDatas => _childMapperDatas;
334334

335335
public int DataSourceIndex { get; set; }
336336

AgileMapper/ObjectPopulation/ObjectMapperFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
namespace AgileObjects.AgileMapper.ObjectPopulation
22
{
33
using System.Collections.Generic;
4-
using System.Linq;
54
using System.Linq.Expressions;
65
using Caching;
76
using ComplexTypes;
87
using Enumerables;
8+
using Extensions;
99

1010
internal class ObjectMapperFactory
1111
{
12-
private readonly IEnumerable<MappingExpressionFactoryBase> _mappingExpressionFactories;
12+
private readonly IList<MappingExpressionFactoryBase> _mappingExpressionFactories;
1313
private readonly List<ICacheEmptier> _rootCacheEmptiers;
1414

1515
public ObjectMapperFactory(MapperContext mapperContext)

AgileMapper/Plans/MappingPlanData.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#if NET_STANDARD
66
using System.Reflection;
77
#endif
8+
using Extensions;
89
using Members;
910
using ObjectPopulation;
1011
using ReadableExpressions;

0 commit comments

Comments
 (0)