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





5.00/5 (9投票s)
本文展示了如何使用扩展方法,例如,对基于索引的泛型列表进行排序。
引言和背景
自从 .NET Framework 3.0 以来,开发人员拥有一个有趣的工具,可以使其在不派生或重新编译的情况下向已存在的类型添加方法。例如,LINQ 标准操作符通过向接口 System.Collections.IEnumerable
和 System.Collections.IEnumerable<T>
添加查询功能,利用了这个概念,这被称为 **扩展方法**。因此,任何实现这些接口之一的类型似乎都具有诸如 GroupBy
、Where
等实例方法,尽管这些只是对它们的扩展,并且无法在各自的原始类型实现中找到。
**扩展方法**是静态方法,可以使用实例方法语法调用。它们使得向现有类型添加额外方法成为可能。
本文展示了如何使用这个概念来排序基于索引的泛型列表。
排序泛型基于索引的列表
当您浏览类型 System.Array
、System.Collections.ArrayList
和 System.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 日