65.9K
CodeProject 正在变化。 阅读更多。
Home

扩展方法示例:排序基于索引的泛型列表

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2008 年 7 月 19 日

CPOL

2分钟阅读

viewsIcon

36614

downloadIcon

177

本文展示了如何使用扩展方法,例如,对基于索引的泛型列表进行排序。

引言和背景

自从 .NET Framework 3.0 以来,开发人员拥有一个有趣的工具,可以使其在不派生或重新编译的情况下向已存在的类型添加方法。例如,LINQ 标准操作符通过向接口 System.Collections.IEnumerableSystem.Collections.IEnumerable<T> 添加查询功能,利用了这个概念,这被称为 **扩展方法**。因此,任何实现这些接口之一的类型似乎都具有诸如 GroupByWhere 等实例方法,尽管这些只是对它们的扩展,并且无法在各自的原始类型实现中找到。

**扩展方法**是静态方法,可以使用实例方法语法调用。它们使得向现有类型添加额外方法成为可能。

本文展示了如何使用这个概念来排序基于索引的泛型列表。

排序泛型基于索引的列表

当您浏览类型 System.ArraySystem.Collections.ArrayListSystem.Collections.Generic.List<T> 的实例方法时,您可以找到一个方法 Sort。因此,对这些类型之一的列表进行排序很容易。

ArrayList list = new ArrayList() {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort();

然而,观察其他基于索引的集合,您会发现缺少一个排序方法。由于每个基于索引的集合都实现了 System.Collections.Generic.IList<T>,因此类似于上述的调用将会失败。

IList<int> list = new int[10] {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort(); //Compiler error, for IList<T> doesn't possess a method Sort()

因此,您要么将集合转换为上述合适的集合类型之一,要么实现您自己的排序算法。而此时,扩展方法的概念就派上用场了。与其简单地实现一个将 IList<T> 作为其参数的方法,不如创建一个扩展方法,该方法适用于每个实现 IList<T> 的类型,然后可以像在 ArrayList 示例中一样使用它。

扩展方法是在 static 类中实现的。重要的是,扩展方法必须具有修饰符 this,后跟要扩展的类型作为其第一个参数。

示例代码

在此示例中,我实现了 **冒泡排序** 算法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 

namespace Extensions
{
    public static class SortingExtensionProvider
    {
        public static void Sort<T>(this IList<T> list) where T : IComparable
        {
            //This extension method is visible where the namespace
            //Extensions is brought into scope

            Sort(list, 0, list.Count - 1);
        }

        public static void Sort<T>(this IList<T> list, 
               int startIndex, int endIndex) where T : IComparable
        {
            //This extension method is visible where the namespace
            //Extensions is brought into scope

            //Bubble Sort
            for (int i = startIndex; i < endIndex; i++)
                for (int j = endIndex; j > i; j--)
                    if (list[j].IsLesserThan(list[j - 1]))
                        list.Exchange(j, j - 1);
        }

        private static void Exchange<T>(this IList<T> list, int index1, int index2)
        {
            //This extension methods is only visible within SortingExtensionsProvider

            T tmp = list[index1];
            list[index1] = list[index2];
            list[index2] = tmp;
        }

        private static bool IsLesserThan(this IComparable value, IComparable item)
        {
            //This extension method is only visible within SortingExtensionsProvider

            return value.CompareTo(item) < 0;
        }
    }
}

请注意,private 方法 Exchange<T>IsLesserThan 也是扩展方法,但它们仅在类 SortingExtensionProvider 中可见。

现在,如果您通过 using 指令将命名空间 Extensions 引入作用域,则 IList<T> 将具有一个额外的 Sort 方法(确切地说:两个)。

using Extensions;
...
IList<int> list = new int[10] {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort(); //Extension method

历史

  • 更新:2008 年 7 月 25 日
  • 更新:2008 年 8 月 1 日
  • 更新:2008 年 8 月 23 日
© . All rights reserved.