From 1c7dcfa0d514166ee24e8aab17f886eddd45f940 Mon Sep 17 00:00:00 2001 From: Bradley Grainger Date: Thu, 8 Apr 2010 20:13:52 -0700 Subject: [PATCH] Added argument validation, compatibility with OrderBy behaviour for null 'comparer'. --- src/Logos.Utility/EnumerableUtility.cs | 18 +++++++-- .../OrderedEnumerableTests.cs | 40 +++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/Logos.Utility/EnumerableUtility.cs b/src/Logos.Utility/EnumerableUtility.cs index 4e0e9b4..9de4e2d 100644 --- a/src/Logos.Utility/EnumerableUtility.cs +++ b/src/Logos.Utility/EnumerableUtility.cs @@ -31,7 +31,7 @@ public static IEnumerable EmptyIfNull(this IEnumerable source) /// elements that are requested from the return value. public static IOrderedEnumerable LazyOrderBy(this IEnumerable source, Func keySelector) { - return LazyOrderBy(source, keySelector, Comparer.Default); + return LazyOrderBy(source, keySelector, null, false); } /// @@ -45,7 +45,7 @@ public static IEnumerable EmptyIfNull(this IEnumerable source) /// elements that are requested from the return value. public static IOrderedEnumerable LazyOrderBy(this IEnumerable source, Func keySelector, IComparer comparer) { - return new OrderedEnumerable(source, new ElementComparer(keySelector, comparer, false, null)); + return LazyOrderBy(source, keySelector, comparer, false); } /// @@ -58,7 +58,7 @@ public static IEnumerable EmptyIfNull(this IEnumerable source) /// elements that are requested from the return value. public static IOrderedEnumerable LazyOrderByDescending(this IEnumerable source, Func keySelector) { - return LazyOrderByDescending(source, keySelector, Comparer.Default); + return LazyOrderBy(source, keySelector, null, true); } /// @@ -72,7 +72,17 @@ public static IEnumerable EmptyIfNull(this IEnumerable source) /// elements that are requested from the return value. public static IOrderedEnumerable LazyOrderByDescending(this IEnumerable source, Func keySelector, IComparer comparer) { - return new OrderedEnumerable(source, new ElementComparer(keySelector, comparer, true, null)); + return LazyOrderBy(source, keySelector, comparer, true); + } + + private static IOrderedEnumerable LazyOrderBy(this IEnumerable source, Func keySelector, IComparer comparer, bool descending) + { + if (source == null) + throw new ArgumentNullException("source"); + if (keySelector == null) + throw new ArgumentNullException("keySelector"); + + return new OrderedEnumerable(source, new ElementComparer(keySelector, comparer ?? Comparer.Default, descending, null)); } /// diff --git a/tests/Logos.Utility.Tests/OrderedEnumerableTests.cs b/tests/Logos.Utility.Tests/OrderedEnumerableTests.cs index 22a5aaa..3025430 100644 --- a/tests/Logos.Utility.Tests/OrderedEnumerableTests.cs +++ b/tests/Logos.Utility.Tests/OrderedEnumerableTests.cs @@ -138,6 +138,46 @@ public void SortFirstDescendingCustom() CollectionAssert.AreEqual(sorted1, sorted2); } + [Test] + public void AscendingNullArguments() + { + Assert.Throws(() => ((IEnumerable) null).OrderBy(x => x)); + Assert.Throws(() => Enumerable.Range(0, 10).OrderBy((Func) null)); + } + + [Test] + public void DescendingNullArguments() + { + Assert.Throws(() => ((IEnumerable) null).OrderByDescending(x => x)); + Assert.Throws(() => Enumerable.Range(0, 10).OrderByDescending((Func) null)); + } + + [Test] + public void DefaultComparerAscending() + { + Random random = new Random(9); + int[] numbers = new int[100000]; + for (int index = 0; index < numbers.Length; index++) + numbers[index] = random.Next(); + + var sorted1 = numbers.OrderBy(x => x, null); + var sorted2 = numbers.LazyOrderBy(x => x, null); + CollectionAssert.AreEqual(sorted1, sorted2); + } + + [Test] + public void DefaultComparerDescending() + { + Random random = new Random(9); + int[] numbers = new int[100000]; + for (int index = 0; index < numbers.Length; index++) + numbers[index] = random.Next(); + + var sorted1 = numbers.OrderByDescending(x => x, null); + var sorted2 = numbers.LazyOrderByDescending(x => x, null); + CollectionAssert.AreEqual(sorted1, sorted2); + } + // The Triple struct can be used to verify that the sort is stable by sorting by the First (and Second) // properties, then using the Third property to verify that objects are in the right order. [DebuggerDisplay("F={m_first} S={m_second} T={m_third}")]