在微软的.net framework框架中我们知道String有一个Replace的方法,今天我们来实现一个LINQ风格的基于集合Replace元素的扩展方法。首先来看一下,简单类图:

2012-12-22_210823
     下面是主要代码片断:

   1:     /// <summary>
   2:      /// ReplaceExtensions which is LINQ Style Replace Operator
   3:      /// </summary>
   4:      public static class ReplaceExtensions
   5:      {
   6:          /// <summary>
   7:          /// Replaces the specified sequence.
   8:          /// </summary>
   9:          /// <typeparam name="T"></typeparam>
  10:          /// <param name="sequence">The sequence.</param>
  11:          /// <param name="find">The find.</param>
  12:          /// <param name="replaceWith">The replace with.</param>
  13:          /// <param name="comparer">The comparer.</param>
  14:          /// <returns>Collection of type T</returns>
  15:          public static IEnumerable<T> Replace<T>(
  16:      this IEnumerable<T> sequence, T find, T replaceWith, IEqualityComparer<T> comparer)
  17:          {
  18:              if (sequence == null) throw new ArgumentNullException("sequence");
  19:              if (comparer == null) throw new ArgumentNullException("comparer");
  20:   
  21:              return ReplaceImpl(sequence, find, replaceWith, comparer);
  22:          }
  23:   
  24:          /// <summary>
  25:          /// Replaces the specified sequence.
  26:          /// </summary>
  27:          /// <typeparam name="T"></typeparam>
  28:          /// <param name="sequence">The sequence.</param>
  29:          /// <param name="find">The find.</param>
  30:          /// <param name="replaceWith">The replace with.</param>
  31:          /// <returns>Collection of type T</returns>
  32:          public static IEnumerable<T> Replace<T>(
  33:      this IEnumerable<T> sequence, T find, T replaceWith)
  34:          {
  35:              return Replace(sequence, find, replaceWith, EqualityComparer<T>.Default);
  36:          }
  37:   
  38:          /// <summary>
  39:          /// Replaces the impl.
  40:          /// </summary>
  41:          /// <typeparam name="T"></typeparam>
  42:          /// <param name="sequence">The sequence.</param>
  43:          /// <param name="find">The find.</param>
  44:          /// <param name="replaceWith">The replace with parameter</param>
  45:          /// <param name="comparer">The comparer.</param>
  46:          /// <returns>Collection of type T</returns>
  47:          private static IEnumerable<T> ReplaceImpl<T>(
  48:      IEnumerable<T> sequence, T find, T replaceWith, IEqualityComparer<T> comparer)
  49:          {
  50:              foreach (T item in sequence)
  51:              {
  52:                  bool match = comparer.Equals(find, item);
  53:                  T x = match ? replaceWith : item;
  54:                  yield return x;
  55:              }
  56:          }
  57:      }


从代码应该不难看懂,我们使用IEqualityComparer<T>,  然后Equals, 接着使用了yield, 您可以根据需求实现自己的实现类。这样我们就能实现类似LINQ风格的Replace集合元素扩展,看下面的UnitTest:

   1:          [TestMethod]
   2:          public void Single_IntCollection_Replace_Should_Same()
   3:          {
   4:              //Arranage
   5:              int[] values = new int[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
   6:   
   7:              //Act
   8:              int[] replaced = values.Replace(3, 0).ToArray();
   9:   
  10:              //Assert
  11:              CollectionAssert.AreEqual(new int[] { 1, 2, 0, 4, 5, 4, 0, 2, 1 }, replaced,"Results should be same.");
  12:          }
  13:   
  14:          [TestMethod]
  15:          public void StringCollection_Replace_Should_Same()
  16:          {
  17:              //Arrange
  18:              string[] strings = new string[] { "A", "B", "C", "D", "a", "b", "c", "d" };
  19:   
  20:              //Act
  21:              string[] replacedCS = strings.Replace("b", "-").ToArray();
  22:              string[] replacedCI = strings.Replace("b", "-", StringComparer.InvariantCultureIgnoreCase).ToArray();
  23:   
  24:              //Assert
  25:              CollectionAssert.AreEqual(new string[] { "A", "B", "C", "D", "a", "-", "c", "d" }, replacedCS, "Results should be same.");
  26:              CollectionAssert.AreEqual(new string[] { "A", "-", "C", "D", "a", "-", "c", "d" }, replacedCI, "Results should be same.");
  27:          }


基于MsTest的单元测试,您了解的话,应该不难看懂上面的代码。
希望对您CSharp编码有帮助。

您可能感兴趣的文章:

为IEnumerable<T>增加Combine的扩展方法
IEnumerable的扩展方法


作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog

posted on 2012-12-22 21:41  PetterLiu  阅读(1674)  评论(0编辑  收藏  举报