为什么IList 没有排序?!?! (编辑)的

当我发现没有直接的方法对IList 进行排序或执行二进制搜索时,我感到非常惊讶。 就像有一些静态方法来对数组进行排序和执行二进制搜索一样,我认为使用类似于IList 的静态方法会非常有帮助。

目前:

class Array { static Sort(T[] array); static int BinarySearch(T[] array, T item); } 

我希望他们会补充:

 class List { static Sort(IList list); static int BinarySearch(IList list, T item); } 

我瞥了一眼.NET Framework 4.0 Beta SDK,似乎仍然没有解决这个问题的方法。

我知道我可以通过创建一个扩展方法来解决这个问题,该方法检查它是否是List 然后使用List 实例进行排序/搜索; 但是,如果它不是List 的实例,那么我必须执行一个副本(对于非常大的列表很臭)。 我知道我可以做到这一切,但为什么呢? 有没有理由他们故意省略这个function?

为了尝试在.NET 4.0 Framework中实现这一点,我通过Microsoft的Connect程序创建了一个建议。 如果你像我一样对这个问题感到沮丧,那就投票吧,也许它会被添加。

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=474201

LINQ有一个OrderBy方法,适用于所有IEnumerable ,包括IList 。 你可以使用OrderBy完成同样的事情。

 // Order a list of addresses: IList list = ... var orderedList = list.OrderBy(input => input); 

我认为不包括IList的排序方法是一个很好的例子。 首先,它会为那些想要实现IList的人带来额外的复杂性,第二,它会使IList接口更难以符合接口隔离原则 。

一般来说,如果我需要对IList执行排序,我会创建一个新的List并传入IList作为参数

例如:

  public IList
SortAddresses(IList
addresses) { var sortedAddresses = new List
(addresses); sortedAddresses.Sort(); return sortedAddresses; }

好消息是你可以很容易地写出这样的方法; 并且感谢C#3.0扩展方法,您可以在界面上进行此操作:

 public static class ListExt { public static void AddRange(this IList list, IEnumerable items) { foreach(T item in items) list.Add(item); } public static void Sort(this IList list) { Sort(list,Comparer.Default); // ordinal sort by default } public static void Sort(this IList list, IComparer comparer) { // very poor implementation! List concreteList = new List(list); concreteList.Sort(comparer); // cheat! list.Clear(); list.AddRange(concreteList); } public static int BinarySearch(this IList list, T item) { return BinarySearch(list, item, Comparer.Default); } public static int BinarySearch(this IList list, T item, IComparer comparer) {...} // TODO } 

现在剩下的就是TODO代码本身(和probaby重写Sort ;-p); 但在那之后:

 IList list = ... list.Sort(); T huntFor = ... int i = list.BinarySearch(huntFor); 

重要的是, IList有一个读/写索引器,所以当然可以在没有上面的hack的情况下进行排序和二进制搜索。

你确实有ArrayList.Adapter允许使用ArrayList的排序例程,但它会对未装箱值类型的通用列表,以及虚拟调用和接口调度开销产生巨大的性能影响。

对于引用和值类型,接口调度可能很昂贵,这意味着调用ICollection.CopyTo数组T[]后跟单独的排序可能是最快的通用选项,包括直接排序的自定义扩展IList对象。

List有一个Sort方法,因为它可以非常有效地对T[]类型的底层数组进行操作。 对于任意IList根本无法做到这一点。

我不是C#专家,但很少有List实现支持排序,二进制搜索甚至索引检索。 列表通常基于链表 ,这些链表通常不提供通过其索引检索项的O(1)方式。 如果要快速定位元素,则使用某些内容按照其他人的建议将元素按照排序顺序保存,如树或数组。

我确实发现IList包含一个有趣的索引检索方法 。 您可能想要考虑使用SortedList而不是List因为它看起来应该支持在O(1)时间内通过索引或键进行查找。 通常,如果您需要支持快速查找的内容,那么请查找保持其元素顺序而不是显式排序的数据结构。 如果不出意外,C#已经有了很多数据结构。