diff --git a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs index f24636f8..d151069f 100644 --- a/Src/Newtonsoft.Json/Utilities/LinqBridge.cs +++ b/Src/Newtonsoft.Json/Utilities/LinqBridge.cs @@ -72,7 +72,14 @@ namespace Newtonsoft.Json.Utilities.LinqBridge { CheckNotNull(source, "source"); - return CastYield(source); + var servesItself = source as IEnumerable; + if (servesItself != null + && (!(servesItself is TResult[]) || servesItself.GetType().GetElementType() == typeof(TResult))) + { + return servesItself; + } + + return CastYield(source); } private static IEnumerable CastYield( @@ -151,11 +158,20 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func predicate) { + CheckNotNull(source, "source"); CheckNotNull(predicate, "predicate"); - return source.Where((item, i) => predicate(item)); + return WhereYield(source, predicate); } + private static IEnumerable WhereYield( + IEnumerable source, + Func predicate) + { + foreach (var item in source) + if (predicate(item)) + yield return item; + } /// /// Filters a sequence of values based on a predicate. /// Each element's index is used in the logic of the predicate function. @@ -189,9 +205,18 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func selector) { + CheckNotNull(source, "source"); CheckNotNull(selector, "selector"); - return source.Select((item, i) => selector(item)); + return SelectYield(source, selector); + } + + private static IEnumerable SelectYield( + IEnumerable source, + Func selector) + { + foreach (var item in source) + yield return selector(item); } /// @@ -612,9 +637,7 @@ namespace Newtonsoft.Json.Utilities.LinqBridge private static IEnumerable ReverseYield(IEnumerable source) { - var stack = new Stack(); - foreach (var item in source) - stack.Push(item); + var stack = new Stack(source); foreach (var item in stack) yield return item; @@ -706,9 +729,21 @@ namespace Newtonsoft.Json.Utilities.LinqBridge CheckNotNull(source, "source"); var collection = source as ICollection; - return collection != null - ? collection.Count - : source.Aggregate(0, (count, item) => checked(count + 1)); + if (collection != null) + { + return collection.Count; + } + + using (var en = source.GetEnumerator()) + { + int count = 0; + while (en.MoveNext()) + { + ++count; + } + + return count; + } } /// @@ -788,17 +823,25 @@ namespace Newtonsoft.Json.Utilities.LinqBridge return new List(source); } - /// - /// Creates an array from an . - /// + /// + /// Creates an array from an . + /// - public static TSource[] ToArray( - this IEnumerable source) - { - return source.ToList().ToArray(); - } + public static TSource[] ToArray( + this IEnumerable source) + { + IList ilist = source as IList; + if (ilist != null) + { + TSource[] array = new TSource[ilist.Count]; + ilist.CopyTo(array, 0); + return array; + } - /// + return source.ToList().ToArray(); + } + + /// /// Returns distinct elements from a sequence by using the default /// equality comparer to compare values. /// @@ -1221,7 +1264,15 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func predicate) { - return source.Where(predicate).Any(); + foreach (TSource item in source) + { + if (predicate(item)) + { + return true; + } + } + + return false; } /// @@ -2546,7 +2597,16 @@ namespace Newtonsoft.Json.Utilities.LinqBridge this IEnumerable source, Func selector) { - return source.Select(selector).Sum(); + CheckNotNull(source, "source"); + CheckNotNull(selector, "selector"); + + decimal sum = 0; + foreach (TSource item in source) + { + sum += selector(item); + } + + return sum; } ///