PageRenderTime 705ms CodeModel.GetById 401ms app.highlight 5ms RepoModel.GetById 297ms app.codeStats 0ms

/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}