/Utilities/Collections/EnumerableExtensions.cs
C# | 151 lines | 95 code | 10 blank | 46 comment | 0 complexity | f16739cab01468794a14c215d52cca9b MD5 | raw file
1using System; 2using System.Collections.Generic; 3using NUnit.Framework; 4 5namespace Delta.Utilities.Collections 6{ 7 /// <summary> 8 /// Extensions to <see cref="IEnumerable{T}"/>, make sure to use this 9 /// namespace when using this extensions. Includes ForEach, TryDo, Do and 10 /// EnumerateAll methods for IEnumerable items. 11 /// </summary> 12 public static class EnumerableExtensions 13 { 14 #region ForEach (Static) 15 /// <summary> 16 /// Iterates the <paramref name="source"/> and applies the 17 /// <paramref name="action"/> to each item. 18 /// </summary> 19 /// <typeparam name="TItem">TItem</typeparam> 20 /// <param name="action">Action</param> 21 /// <param name="source">Source</param> 22 public static void ForEach<TItem>(this IEnumerable<TItem> source, 23 Action<TItem> action) 24 { 25 foreach (var item in source) 26 { 27 action(item); 28 } 29 } 30 #endregion 31 32 #region TryDo (Static) 33 /// <summary> 34 /// Allows chaining actions on a set of items for later processing, 35 /// filtering or projection (transformation), ignoring exceptions that 36 /// might happen in the action. 37 /// </summary> 38 /// <typeparam name="T">T</typeparam> 39 /// <param name="action">Action</param> 40 /// <param name="source">Source</param> 41 /// <returns>An enumeration with the same items as the source.</returns> 42 public static IEnumerable<T> TryDo<T>(this IEnumerable<T> source, 43 Action<T> action) 44 { 45 foreach (var item in source) 46 { 47 try 48 { 49 action(item); 50 } 51 catch 52 { 53 } 54 55 yield return item; 56 } 57 } 58 #endregion 59 60 #region Do (Static) 61 /// <summary> 62 /// Allows chaining actions on a set of items for later processing, 63 /// filtering or projection (transformation). 64 /// </summary> 65 /// <typeparam name="T">T</typeparam> 66 /// <param name="action">Action</param> 67 /// <param name="source">Source</param> 68 /// <returns>An enumeration with the same items as the source.</returns> 69 public static IEnumerable<T> Do<T>(this IEnumerable<T> source, 70 Action<T> action) 71 { 72 foreach (var item in source) 73 { 74 action(item); 75 yield return item; 76 } 77 } 78 #endregion 79 80 #region EnumerateAll (Static) 81 /// <summary> 82 /// Enumerates all elements in the source, so that any intermediate 83 /// action or side-effect from it is performed eagerly. 84 /// Note: Does nothing inside the enumeration! 85 /// </summary> 86 /// <typeparam name="T">T</typeparam> 87 /// <param name="source">Source</param> 88 public static void EnumerateAll<T>(this IEnumerable<T> source) 89 { 90 foreach (var item in source) 91 { 92 } 93 } 94 #endregion 95 96 /// <summary> 97 /// Tests for EnumerableExtensions. Not really useful, we just use some 98 /// numbers to test the functionality, but in order to use this class for 99 /// real a state machine (e.g. for AI) should be used. 100 /// </summary> 101 internal class EnumerableExtensionsTests 102 { 103 #region TestForEach 104 [Test] 105 public void TestForEach() 106 { 107 List<int> someNumbers = new List<int>(); 108 someNumbers.Add(1); 109 someNumbers.Add(2); 110 someNumbers.Add(5); 111 someNumbers.Add(10); 112 113 // And add all numbers 114 int allNumbers = 0; 115 someNumbers.ForEach(delegate(int number) 116 { 117 allNumbers += number; 118 }); 119 Assert.Equal(allNumbers, 1 + 2 + 5 + 10); 120 } 121 #endregion 122 123 #region TestDo 124 [Test, Category("LongRunning")] 125 public void TestDo() 126 { 127 List<int> someNumbers = new List<int>(); 128 someNumbers.Add(1); 129 someNumbers.Add(2); 130 someNumbers.Add(5); 131 someNumbers.Add(10); 132 133 // Define action what to do when calling the Do method below 134 Action<int> printNumberAndSquare = delegate(int number) 135 { 136 Console.WriteLine( 137 "Number: " + number + ", Square: " + number * number); 138 }; 139 140 // And print them all out, calling them one by one 141 // Note: This is obviously not very useful code, it just shows how 142 // to use the Do method. You need more useful state machine code! 143 foreach (int number in someNumbers.Do(printNumberAndSquare)) 144 { 145 Console.WriteLine("Processed number: " + number); 146 } 147 } 148 #endregion 149 } 150 } 151}