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