-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Enumerable.TryGetNonEnumeratedCount (Implements #27183) #48239
Changes from all commits
378fc7c
6b140e6
39fd614
7b2f59c
4f8023a
331fd78
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,4 +3,4 @@ | |
<PropertyGroup> | ||
<StrongNameKeyId>Microsoft</StrongNameKeyId> | ||
</PropertyGroup> | ||
</Project> | ||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,6 +72,59 @@ public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, | |
return count; | ||
} | ||
|
||
/// <summary> | ||
/// Attempts to determine the number of elements in a sequence without forcing an enumeration. | ||
/// </summary> | ||
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam> | ||
/// <param name="source">A sequence that contains elements to be counted.</param> | ||
/// <param name="count"> | ||
/// When this method returns, contains the count of <paramref name="source" /> if successful, | ||
/// or zero if the method failed to determine the count.</param> | ||
/// <returns> | ||
/// <see langword="true" /> if the count of <paramref name="source"/> can be determined without enumeration; | ||
/// otherwise, <see langword="false" />. | ||
/// </returns> | ||
/// <remarks> | ||
/// The method performs a series of type tests, identifying common subtypes whose | ||
/// count can be determined without enumerating; this includes <see cref="ICollection{T}"/>, | ||
/// <see cref="ICollection"/> as well as internal types used in the LINQ implementation. | ||
/// | ||
/// The method is typically a constant-time operation, but ultimately this depends on the complexity | ||
/// characteristics of the underlying collection implementation. | ||
/// </remarks> | ||
public static bool TryGetNonEnumeratedCount<TSource>(this IEnumerable<TSource> source, out int count) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't need to be generic? if it does, I think a non-generic overload would also make sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could do that, however it becomes more difficult to check for generic interfaces, which would require some form of reflection. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's definitely a no-go because the point of using this is performance. Perhaps those generic interfaces need a non-generic base with |
||
{ | ||
if (source == null) | ||
{ | ||
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.source); | ||
} | ||
|
||
if (source is ICollection<TSource> collectionoft) | ||
{ | ||
count = collectionoft.Count; | ||
return true; | ||
} | ||
|
||
if (source is IIListProvider<TSource> listProv) | ||
{ | ||
int c = listProv.GetCount(onlyIfCheap: true); | ||
if (c >= 0) | ||
{ | ||
count = c; | ||
return true; | ||
} | ||
} | ||
|
||
if (source is ICollection collection) | ||
{ | ||
count = collection.Count; | ||
return true; | ||
} | ||
|
||
eiriktsarpalis marked this conversation as resolved.
Show resolved
Hide resolved
|
||
count = 0; | ||
return false; | ||
} | ||
|
||
public static long LongCount<TSource>(this IEnumerable<TSource> source) | ||
{ | ||
if (source == null) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: using System.Linq;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to avoid bringing all the enumerable methods into scope since this is a System.Collections namespace.