22using System . Collections ;
33using System . Collections . Generic ;
44using System . Linq ;
5- using JetBrains . Annotations ;
65using System . Runtime . CompilerServices ;
6+ using JetBrains . Annotations ;
77using Light . GuardClauses . Exceptions ;
88using NotNullAttribute = System . Diagnostics . CodeAnalysis . NotNullAttribute ;
99
@@ -25,7 +25,7 @@ public static class EnumerableExtensions
2525 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
2626 [ ContractAnnotation ( "source:null => halt; source:notnull => notnull" ) ]
2727 // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
28- public static IList < T > AsList < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > source ) =>
28+ public static IList < T > AsList < T > ( [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > source ) =>
2929 source as IList < T > ?? source . ToList ( ) ;
3030
3131 /// <summary>
@@ -39,9 +39,13 @@ public static IList<T> AsList<T>([NotNull, ValidatedNotNull] this IEnumerable<T>
3939 /// <exception cref="ArgumentNullException">Thrown when <paramref name="source" /> or <paramref name="createCollection" /> is null.</exception>
4040 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
4141 [ ContractAnnotation ( "source:null => halt; source:notnull => notnull; createCollection:null => halt" ) ]
42- // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
43- public static IList < T > AsList < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > source , Func < IEnumerable < T > , IList < T > > createCollection ) =>
44- source as IList < T > ?? createCollection . MustNotBeNull ( nameof ( createCollection ) ) ( source . MustNotBeNull ( nameof ( source ) ) ) ;
42+ public static IList < T > AsList < T > (
43+ // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
44+ [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > source ,
45+ Func < IEnumerable < T > , IList < T > > createCollection
46+ ) =>
47+ source as IList < T > ??
48+ createCollection . MustNotBeNull ( nameof ( createCollection ) ) ( source . MustNotBeNull ( nameof ( source ) ) ) ;
4549
4650 /// <summary>
4751 /// Tries to downcast the specified enumerable to an array, or creates a new array with the specified items.
@@ -53,7 +57,8 @@ public static IList<T> AsList<T>([NotNull, ValidatedNotNull] this IEnumerable<T>
5357 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
5458 [ ContractAnnotation ( "source:null => halt; source:notnull => notnull" ) ]
5559 // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
56- public static T [ ] AsArray < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > source ) => source as T [ ] ?? source . ToArray ( ) ;
60+ public static T [ ] AsArray < T > ( [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > source ) =>
61+ source as T [ ] ?? source . ToArray ( ) ;
5762
5863 /// <summary>
5964 /// Performs the action on each item of the specified enumerable. If the enumerable contains items that are null, this
@@ -65,8 +70,12 @@ public static IList<T> AsList<T>([NotNull, ValidatedNotNull] this IEnumerable<T>
6570 /// <param name="throwWhenItemIsNull">The value indicating whether this method should throw a <see cref="CollectionException" /> when any of the items is null (optional). Defaults to true.</param>
6671 /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable" /> or <paramref name="action" /> is null.</exception>
6772 /// <exception cref="CollectionException">Thrown when <paramref name="enumerable" /> contains a value that is null and <paramref name="throwWhenItemIsNull" /> is set to true.</exception>
68- // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
69- public static IEnumerable < T > ForEach < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > enumerable , Action < T > action , bool throwWhenItemIsNull = true )
73+ public static IEnumerable < T > ForEach < T > (
74+ // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
75+ [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > enumerable ,
76+ Action < T > action ,
77+ bool throwWhenItemIsNull = true
78+ )
7079 {
7180 // ReSharper disable PossibleMultipleEnumeration
7281 action . MustNotBeNull ( nameof ( action ) ) ;
@@ -79,7 +88,14 @@ public static IEnumerable<T> ForEach<T>([NotNull, ValidatedNotNull] this IEnumer
7988 var item = list [ i ] ;
8089 if ( item is null )
8190 {
82- if ( throwWhenItemIsNull ) throw new CollectionException ( nameof ( enumerable ) , $ "The collection contains null at index { i } .") ;
91+ if ( throwWhenItemIsNull )
92+ {
93+ throw new CollectionException (
94+ nameof ( enumerable ) ,
95+ $ "The collection contains null at index { i } ."
96+ ) ;
97+ }
98+
8399 continue ;
84100 }
85101
@@ -92,7 +108,14 @@ public static IEnumerable<T> ForEach<T>([NotNull, ValidatedNotNull] this IEnumer
92108 {
93109 if ( item is null )
94110 {
95- if ( throwWhenItemIsNull ) throw new CollectionException ( nameof ( enumerable ) , $ "The collection contains null at index { i } .") ;
111+ if ( throwWhenItemIsNull )
112+ {
113+ throw new CollectionException (
114+ nameof ( enumerable ) ,
115+ $ "The collection contains null at index { i } ."
116+ ) ;
117+ }
118+
96119 ++ i ;
97120 continue ;
98121 }
@@ -117,7 +140,7 @@ public static IEnumerable<T> ForEach<T>([NotNull, ValidatedNotNull] this IEnumer
117140 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
118141 [ ContractAnnotation ( "source:null => halt; source:notnull => notnull" ) ]
119142 // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
120- public static IReadOnlyList < T > AsReadOnlyList < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > source ) =>
143+ public static IReadOnlyList < T > AsReadOnlyList < T > ( [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > source ) =>
121144 source as IReadOnlyList < T > ?? source . ToList ( ) ;
122145
123146 /// <summary>
@@ -132,25 +155,34 @@ public static IReadOnlyList<T> AsReadOnlyList<T>([NotNull, ValidatedNotNull] thi
132155 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
133156 [ ContractAnnotation ( "source:null => halt; source:notnull => notnull; createCollection:null => halt" ) ]
134157 // ReSharper disable RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
135- public static IReadOnlyList < T > AsReadOnlyList < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > source , [ NotNull , ValidatedNotNull ] Func < IEnumerable < T > , IReadOnlyList < T > > createCollection ) =>
136- source as IReadOnlyList < T > ?? createCollection . MustNotBeNull ( nameof ( createCollection ) ) ( source . MustNotBeNull ( nameof ( source ) ) ) ;
158+ public static IReadOnlyList < T > AsReadOnlyList < T > (
159+ [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > source ,
160+ [ NotNull ] [ ValidatedNotNull ] Func < IEnumerable < T > , IReadOnlyList < T > > createCollection
161+ ) =>
162+ source as IReadOnlyList < T > ??
163+ createCollection . MustNotBeNull ( nameof ( createCollection ) ) ( source . MustNotBeNull ( nameof ( source ) ) ) ;
137164 // ReSharper restore RedundantNullableFlowAttribute
138165
139166
140167 /// <summary>
141168 /// Gets the count of the specified enumerable.
142169 /// </summary>
143170 /// <param name="enumerable">The enumerable whose count should be determined.</param>
144- /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable"/> is null.</exception>
171+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable" /> is null.</exception>
145172 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
146173 [ ContractAnnotation ( "enumerable:null => halt" ) ]
147174 // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
148- public static int Count ( [ NotNull , ValidatedNotNull ] this IEnumerable enumerable )
175+ public static int Count ( [ NotNull ] [ ValidatedNotNull ] this IEnumerable enumerable )
149176 {
150177 if ( enumerable is ICollection collection )
178+ {
151179 return collection . Count ;
180+ }
181+
152182 if ( enumerable is string @string )
183+ {
153184 return @string . Length ;
185+ }
154186
155187 return DetermineCountViaEnumerating ( enumerable ) ;
156188 }
@@ -159,37 +191,54 @@ public static int Count([NotNull, ValidatedNotNull] this IEnumerable enumerable)
159191 /// Gets the count of the specified enumerable.
160192 /// </summary>
161193 /// <param name="enumerable">The enumerable whose count should be determined.</param>
162- /// <param name="parameterName">The name of the parameter that is passed to the <see cref="ArgumentNullException"/> (optional).</param>
163- /// <param name="message">The message that is passed to the <see cref="ArgumentNullException"/> (optional).</param>
164- /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable"/> is null.</exception>
194+ /// <param name="parameterName">The name of the parameter that is passed to the <see cref="ArgumentNullException" /> (optional).</param>
195+ /// <param name="message">The message that is passed to the <see cref="ArgumentNullException" /> (optional).</param>
196+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable" /> is null.</exception>
165197 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
166198 [ ContractAnnotation ( "enumerable:null => halt" ) ]
167- public static int Count ( [ NotNull , ValidatedNotNull ] this IEnumerable ? enumerable , string ? parameterName , string ? message )
199+ public static int Count (
200+ [ NotNull ] [ ValidatedNotNull ] this IEnumerable ? enumerable ,
201+ string ? parameterName ,
202+ string ? message
203+ )
168204 {
169205 if ( enumerable is ICollection collection )
206+ {
170207 return collection . Count ;
208+ }
209+
171210 if ( enumerable is string @string )
211+ {
172212 return @string . Length ;
213+ }
173214
174215 return DetermineCountViaEnumerating ( enumerable , parameterName , message ) ;
175216 }
176-
217+
177218 /// <summary>
178219 /// Gets the count of the specified enumerable.
179220 /// </summary>
180221 /// <param name="enumerable">The enumerable whose count should be determined.</param>
181- /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable"/> is null.</exception>
222+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable" /> is null.</exception>
182223 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
183224 [ ContractAnnotation ( "enumerable:null => halt" ) ]
184225 // ReSharper disable RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
185- public static int GetCount < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > enumerable )
226+ public static int GetCount < T > ( [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > enumerable )
186227 {
187228 if ( enumerable is ICollection collection )
229+ {
188230 return collection . Count ;
231+ }
232+
189233 if ( enumerable is string @string )
234+ {
190235 return @string . Length ;
236+ }
237+
191238 if ( TryGetCollectionOfTCount ( enumerable , out var count ) )
239+ {
192240 return count ;
241+ }
193242
194243 return DetermineCountViaEnumerating ( enumerable ) ;
195244 }
@@ -198,19 +247,31 @@ public static int GetCount<T>([NotNull, ValidatedNotNull] this IEnumerable<T> en
198247 /// Gets the count of the specified enumerable.
199248 /// </summary>
200249 /// <param name="enumerable">The enumerable whose count should be determined.</param>
201- /// <param name="parameterName">The name of the parameter that is passed to the <see cref="ArgumentNullException"/> (optional).</param>
202- /// <param name="message">The message that is passed to the <see cref="ArgumentNullException"/> (optional).</param>
203- /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable"/> is null.</exception>
250+ /// <param name="parameterName">The name of the parameter that is passed to the <see cref="ArgumentNullException" /> (optional).</param>
251+ /// <param name="message">The message that is passed to the <see cref="ArgumentNullException" /> (optional).</param>
252+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="enumerable" /> is null.</exception>
204253 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
205254 [ ContractAnnotation ( "enumerable:null => halt" ) ]
206- public static int GetCount < T > ( [ NotNull , ValidatedNotNull ] this IEnumerable < T > enumerable , string ? parameterName , string ? message = null )
255+ public static int GetCount < T > (
256+ [ NotNull ] [ ValidatedNotNull ] this IEnumerable < T > enumerable ,
257+ string ? parameterName ,
258+ string ? message = null
259+ )
207260 {
208261 if ( enumerable is ICollection collection )
262+ {
209263 return collection . Count ;
264+ }
265+
210266 if ( enumerable is string @string )
267+ {
211268 return @string . Length ;
269+ }
270+
212271 if ( TryGetCollectionOfTCount ( enumerable , out var count ) )
272+ {
213273 return count ;
274+ }
214275
215276 return DetermineCountViaEnumerating ( enumerable , parameterName , message ) ;
216277 }
@@ -222,6 +283,7 @@ private static bool TryGetCollectionOfTCount<T>([NoEnumeration] this IEnumerable
222283 count = collectionOfT . Count ;
223284 return true ;
224285 }
286+
225287 if ( enumerable is IReadOnlyCollection < T > readOnlyCollection )
226288 {
227289 count = readOnlyCollection . Count ;
@@ -237,24 +299,36 @@ private static int DetermineCountViaEnumerating(IEnumerable? enumerable)
237299 var count = 0 ;
238300 var enumerator = enumerable . MustNotBeNull ( nameof ( enumerable ) ) . GetEnumerator ( ) ;
239301 while ( enumerator . MoveNext ( ) )
302+ {
240303 count ++ ;
304+ }
305+
241306 if ( enumerator is IDisposable disposable )
242307 {
243308 disposable . Dispose ( ) ;
244309 }
310+
245311 return count ;
246312 }
247313
248- private static int DetermineCountViaEnumerating ( [ NotNull ] IEnumerable ? enumerable , string ? parameterName , string ? message )
314+ private static int DetermineCountViaEnumerating (
315+ [ NotNull ] IEnumerable ? enumerable ,
316+ string ? parameterName ,
317+ string ? message
318+ )
249319 {
250320 var count = 0 ;
251321 var enumerator = enumerable . MustNotBeNull ( parameterName , message ) . GetEnumerator ( ) ;
252322 while ( enumerator . MoveNext ( ) )
323+ {
253324 count ++ ;
325+ }
326+
254327 if ( enumerator is IDisposable disposable )
255328 {
256329 disposable . Dispose ( ) ;
257330 }
331+
258332 return count ;
259333 }
260334
@@ -264,9 +338,11 @@ internal static bool ContainsViaForeach<TItem>(this IEnumerable<TItem> items, TI
264338 foreach ( var i in items )
265339 {
266340 if ( equalityComparer . Equals ( i , item ) )
341+ {
267342 return true ;
343+ }
268344 }
269345
270346 return false ;
271347 }
272- }
348+ }
0 commit comments