diff --git a/src/libraries/System.Linq/src/System/Linq/ToCollection.cs b/src/libraries/System.Linq/src/System/Linq/ToCollection.cs index de145c6dccfb19..2fd7f475fafbf4 100644 --- a/src/libraries/System.Linq/src/System/Linq/ToCollection.cs +++ b/src/libraries/System.Linq/src/System/Linq/ToCollection.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Runtime.InteropServices; namespace System.Linq { @@ -108,23 +109,22 @@ public static Dictionary ToDictionary(this IEnumer ThrowHelper.ThrowArgumentNullException(ExceptionArgument.keySelector); } - int capacity = 0; - if (source is ICollection collection) + if (source.TryGetNonEnumeratedCount(out int capacity)) { - capacity = collection.Count; if (capacity == 0) { return new Dictionary(comparer); } - if (collection is TSource[] array) + if (source is TSource[] array) { - return ToDictionary(array, keySelector, comparer); + return SpanToDictionary(array, keySelector, comparer); } - if (collection is List list) + if (source is List list) { - return ToDictionary(list, keySelector, comparer); + ReadOnlySpan span = CollectionsMarshal.AsSpan(list); + return SpanToDictionary(span, keySelector, comparer); } } @@ -137,25 +137,13 @@ public static Dictionary ToDictionary(this IEnumer return d; } - private static Dictionary ToDictionary(TSource[] source, Func keySelector, IEqualityComparer? comparer) where TKey : notnull + private static Dictionary SpanToDictionary(ReadOnlySpan source, Func keySelector, IEqualityComparer? comparer) where TKey : notnull { Dictionary d = new Dictionary(source.Length, comparer); - for (int i = 0; i < source.Length; i++) - { - d.Add(keySelector(source[i]), source[i]); - } - - return d; - } - - private static Dictionary ToDictionary(List source, Func keySelector, IEqualityComparer? comparer) where TKey : notnull - { - Dictionary d = new Dictionary(source.Count, comparer); foreach (TSource element in source) { d.Add(keySelector(element), element); } - return d; } @@ -179,23 +167,22 @@ public static Dictionary ToDictionary(t ThrowHelper.ThrowArgumentNullException(ExceptionArgument.elementSelector); } - int capacity = 0; - if (source is ICollection collection) + if (source.TryGetNonEnumeratedCount(out int capacity)) { - capacity = collection.Count; if (capacity == 0) { return new Dictionary(comparer); } - if (collection is TSource[] array) + if (source is TSource[] array) { - return ToDictionary(array, keySelector, elementSelector, comparer); + return SpanToDictionary(array, keySelector, elementSelector, comparer); } - if (collection is List list) + if (source is List list) { - return ToDictionary(list, keySelector, elementSelector, comparer); + ReadOnlySpan span = CollectionsMarshal.AsSpan(list); + return SpanToDictionary(span, keySelector, elementSelector, comparer); } } @@ -208,25 +195,13 @@ public static Dictionary ToDictionary(t return d; } - private static Dictionary ToDictionary(TSource[] source, Func keySelector, Func elementSelector, IEqualityComparer? comparer) where TKey : notnull + private static Dictionary SpanToDictionary(ReadOnlySpan source, Func keySelector, Func elementSelector, IEqualityComparer? comparer) where TKey : notnull { Dictionary d = new Dictionary(source.Length, comparer); - for (int i = 0; i < source.Length; i++) - { - d.Add(keySelector(source[i]), elementSelector(source[i])); - } - - return d; - } - - private static Dictionary ToDictionary(List source, Func keySelector, Func elementSelector, IEqualityComparer? comparer) where TKey : notnull - { - Dictionary d = new Dictionary(source.Count, comparer); foreach (TSource element in source) { d.Add(keySelector(element), elementSelector(element)); } - return d; }