近期收集一些基于IEnumerable<T>扩展方法,它给我们带了很多便利,有时的确是实用的。其中有Alternate,Append,Prepend,Distinct,Contains。具体怎么用呢,看下面的UnitTest.
Code:
/// <summary> /// IEnumerableExtension /// </summary>public static class IEnumerableExtensions
{ #region Methods (5) // Public Methods (5) /// <summary> /// Alternates the specified first. /// </summary> /// <typeparam name="TSource">The type of the source.</typeparam> /// <param name="first">The first.</param> /// <param name="second">The second.</param> /// <returns></returns>public static IEnumerable<TSource> Alternate<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{ using (IEnumerator<TSource> e1 = first.GetEnumerator()) using (IEnumerator<TSource> e2 = second.GetEnumerator()) while (e1.MoveNext() && e2.MoveNext()) {yield return e1.Current;
yield return e2.Current;
}
}
/// <summary> /// Appends the specified source. /// </summary> /// <typeparam name="TSource">The type of the source.</typeparam> /// <param name="source">The source.</param> /// <param name="element">The element.</param> /// <returns>IEnumerable<TSource></returns>public static IEnumerable<TSource> Append<TSource>(this IEnumerable<TSource> source, TSource element)
{ using (IEnumerator<TSource> e1 = source.GetEnumerator()) while (e1.MoveNext())yield return e1.Current;
yield return element;
}
/// <summary> /// Determines whether [contains] [the specified source]. /// </summary> /// <typeparam name="TSource">The type of the source.</typeparam> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="source">The source.</param> /// <param name="value">The value.</param> /// <param name="selector">The selector.</param> /// <returns> /// <c>true</c> if [contains] [the specified source]; otherwise, <c>false</c>. /// </returns>public static bool Contains<TSource, TResult>(
this IEnumerable<TSource> source, TResult value, Func<TSource, TResult> selector)
{foreach (TSource sourceItem in source)
{TResult sourceValue = selector(sourceItem);
if (sourceValue.Equals(value))
return true;
}
return false;
}
/// <summary> /// Distincts the specified source. /// </summary> /// <typeparam name="TSource">The type of the source.</typeparam> /// <typeparam name="TResult">The type of the result.</typeparam> /// <param name="source">The source.</param> /// <param name="comparer">The comparer.</param> /// <returns>IEnumerable<TSource></returns>public static IEnumerable<TSource> Distinct<TSource, TResult>(
this IEnumerable<TSource> source, Func<TSource, TResult> comparer) {return source.Distinct(new DynamicComparer<TSource, TResult>(comparer));
}
/// <summary> /// Prepends the specified source. /// </summary> /// <typeparam name="TSource">The type of the source.</typeparam> /// <param name="source">The source.</param> /// <param name="element">The element.</param> /// <returns>IEnumerable<TSource></returns>public static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource element)
{yield return element;
using (IEnumerator<TSource> e1 = source.GetEnumerator()) while (e1.MoveNext())yield return e1.Current;
}
#endregion Methods }
/// <summary> /// DynamicComparer /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TResult">The type of the result.</typeparam>public class DynamicComparer<T, TResult> : IEqualityComparer<T>
{ #region Fields (1) private readonly Func<T, TResult> _selector;
#endregion Fields #region Constructors (1) /// <summary> /// Initializes a new instance of the <see cref="DynamicComparer<T, TResult>"/> class. /// </summary> /// <param name="selector">The selector.</param> public DynamicComparer(Func<T, TResult> selector) {_selector = selector;
}
#endregion Constructors #region Methods (2) // Public Methods (2) /// <summary> /// Determines whether the specified objects are equal. /// </summary> /// <param name="x">The first object of type <paramref name="T"/> to compare.</param> /// <param name="y">The second object of type <paramref name="T"/> to compare.</param> /// <returns> /// true if the specified objects are equal; otherwise, false. /// </returns>public bool Equals(T x, T y)
{TResult result1 = _selector(x);
TResult result2 = _selector(y);
return result1.Equals(result2);}
/// <summary> /// Returns a hash code for the specified object. /// </summary> /// <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param> /// <returns>A hash code for the specified object.</returns> /// <exception cref="T:System.ArgumentNullException"> /// The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null. /// </exception>public int GetHashCode(T obj)
{TResult result = _selector(obj);
return result.GetHashCode();}
#endregion Methods }
UnitTest:
1: #region Methods (8)
2: 3: // Public Methods (7)
4: 5: [Test]6: public void Bad_concat_method()
7: {8: var ints = new[] { 1, 2, 3 };
9: 10: var oneToFour = ints.Concat(Enumerable.Repeat(4, 1)); 11: 12: CollectionAssert.AreEqual(new[] { 1, 2, 3, 4 }, oneToFour.ToArray());
13: } 14: 15: [Test]16: public void Better_enumerable_extensions()
17: {18: var values = new[]
19: {20: new Person {FirstName = "Bob", LastName = "Smith"},
21: new Person {FirstName = "Don", LastName = "Allen"},
22: new Person {FirstName = "Bob", LastName = "Sacamano"},
23: new Person {FirstName = "Chris", LastName = "Smith"},
24: new Person {FirstName = "George", LastName = "Allen"}
25: }; 26: 27: Assert.AreEqual(3, values.Distinct(person => person.LastName).Count()); 28: Assert.AreEqual(4, values.Distinct(person => person.FirstName).Count());29: Assert.IsTrue(values.Contains("Smith", person => person.LastName));
30: Assert.IsFalse(values.Contains("Nixon", person => person.LastName));
31: } 32: 33: [Test]34: public void Easier_concat_with_append()
35: {36: var ints = new[] { 1, 2, 3 };
37: 38: var oneToFour = ints.Append(4); 39: 40: CollectionAssert.AreEqual(new[] { 1, 2, 3, 4 }, oneToFour.ToArray());
41: } 42: 43: [Test]44: public void Easier_concat_with_prepend()
45: {46: var ints = new[] { 1, 2, 3 };
47: 48: var zeroToThree = ints.Prepend(0); 49: 50: CollectionAssert.AreEqual(new[] { 0, 1, 2, 3 }, zeroToThree.ToArray());
51: } 52: 53: [Test]54: public void TestAggregate()
55: {56: string sentence = "the quick brown fox jumps over the lazy dog";
57: 58: // Split the string into individual words.
59: string[] words = sentence.Split(' ');
60: 61: // Prepend each word to the beginning of the
62: // new sentence to reverse the word order.
63: string reversed = words.Aggregate((workingSentence, next) =>
64: next + " " + workingSentence);
65: Assert.AreEqual("dog lazy the over jumps fox brown quick the",reversed);
66: } 67: 68: [Test]69: public void TestintArray()
70: {71: int[] aa = new int[] { 1, 3, 5};
72: int[] bb = new int[] { 2, 4, 6 };
73: 74: var cc = aa.Alternate(bb); 75: 76: CollectionAssert.AreEqual(new[] { 1, 2, 3, 4, 5, 6},cc.ToArray());
77: 78: } 79: 80: [Test]81: public void Word_play()
82: {83: var source = new[] { "That", "is", "exactly", "I", "want" };
84: 85: var result = source.Alternate(Spaces()).Aggregate(string.Empty, (a, b) => a + b);
86: 87: 88: foreach (var s in result)
89: { 90: Console.Write(s); 91: }92: //That is exactly I want
93: }94: // Private Methods (1)
95: 96: private IEnumerable<string> Spaces()
97: {98: while (true)
99: yield return " ";
100: } 101: 102: #endregion Methods
Author:Petter Liu http://wintersun.cnblogs.com
希望这篇Post对您有帮助。