C# 为什么没有IList<;T>;?!?!(编辑)
当我发现在IListC# 为什么没有IList<;T>;?!?!(编辑),c#,.net,c#-4.0,C#,.net,C# 4.0,当我发现在IList上没有直接的方法来排序或执行二进制搜索时,我感到非常惊讶。就像有一些静态方法可以对数组进行排序和二进制搜索一样,我认为使用类似的静态方法来执行IList非常有帮助 目前: class Array { static Sort<T>(T[] array); static int BinarySearch<T>(T[] array, T item); } 类数组 { 静态排序(T[]数组); 静态int二进制搜索(T[]数组,T项); }
class Array
{
static Sort<T>(T[] array);
static int BinarySearch<T>(T[] array, T item);
}
类数组
{
静态排序(T[]数组);
静态int二进制搜索(T[]数组,T项);
}
我希望他们能补充:
class List
{
static Sort<T>(IList<T> list);
static int BinarySearch<T>(IList<T> list, T item);
}
类列表
{
静态排序(IList列表);
静态int二进制搜索(IList列表,T项);
}
我浏览了一下.NETFramework4.0BetaSDK,发现似乎仍然不能解决这个问题
我知道我可以通过创建一个扩展方法来解决这个问题,该扩展方法检查它是否是List您确实有
ArrayList.Adapter
,它允许使用ArrayList
的排序例程,但它会对非固定值类型的通用列表造成巨大的性能影响,以及虚拟调用和接口调度开销
对于引用类型和值类型,接口分派可能很昂贵,这意味着调用ICollection.CopyTo
数组T[]
后跟单独排序可能是最快的通用选项,包括一个自定义扩展,可直接对IList
对象进行排序
List
有一个Sort
方法,因为它可以非常有效地对T[]
类型的底层数组进行操作。对于任意的IList
来说,根本没有办法做到这一点。我认为不包括IList
的排序方法是一个很好的理由。首先,对于那些想要实现IList的人来说,这会增加复杂性;其次,这会使IList接口更难符合标准
通常,如果我需要对IList
执行排序,我要做的是创建一个新的列表
,并将IList
作为参数传入
例如:
public IList<Address> SortAddresses(IList<Address> addresses)
{
var sortedAddresses = new List<Address>(addresses);
sortedAddresses.Sort();
return sortedAddresses;
}
公共IList分类地址(IList地址)
{
var sortedAddresses=新列表(地址);
sorted.Sort();
退货;
}
我不是C#专家,但很少有列表实现支持排序、二进制搜索甚至索引检索。列表通常基于此,通常不提供通过索引检索项目的O(1)
方法。如果您想快速定位一个元素,那么可以使用其他人建议的方法来保持元素的排序顺序,比如a或数组
我确实发现,
IList
包含了一个有趣的例子。你可能想考虑使用而不是<代码>列表< /> >,因为它看起来应该支持索引或密钥在<代码> O(1)时间中的查找。一般来说,如果您需要支持快速查找的内容,那么请寻找一种使其元素保持有序而不是显式排序的数据结构。如果没有其他东西的话,C#已经有了相当多的数据结构。LINQ有一个OrderBy方法,可以处理所有IEnumerable,包括IList。您可以使用OrderBy完成相同的任务
// Order a list of addresses:
IList<string> list = ...
var orderedList = list.OrderBy(input => input);
//为地址列表排序:
IList列表=。。。
var orderedList=list.OrderBy(输入=>input);
好消息是,您可以相当容易地编写此类方法;多亏了C#3.0扩展方法,您可以在界面上实现这一点:
public static class ListExt
{
public static void AddRange<T>(this IList<T> list, IEnumerable<T> items) {
foreach(T item in items) list.Add(item);
}
public static void Sort<T>(this IList<T> list) {
Sort<T>(list,Comparer<T>.Default); // ordinal sort by default
}
public static void Sort<T>(this IList<T> list, IComparer<T> comparer)
{ // very poor implementation!
List<T> concreteList = new List<T>(list);
concreteList.Sort(comparer); // cheat!
list.Clear();
list.AddRange(concreteList);
}
public static int BinarySearch<T>(this IList<T> list, T item) {
return BinarySearch<T>(list, item, Comparer<T>.Default);
}
public static int BinarySearch<T>(this IList<T> list, T item,
IComparer<T> comparer)
{...} // TODO
}
重要的是,
IList
有一个读/写索引器,因此当然可以在不使用上述hack的情况下进行排序和二进制搜索。但是,重要的是要意识到这不会对列表进行排序(这可能不是个问题)。@lomaxx:它如何为实现IList的类增加复杂性?索引get/set属性已经存在,这些属性可以简单地用在静态排序(List)方法中。@dewald:因为它需要编写更多的代码,而且对每种类型的集合进行排序没有意义。对不起,不是C#guy。。。如果已经有一个静态排序(列表),那么我肯定同意不需要向接口添加排序函数。Java与之类似:Collections.sort(List)是任何列表的静态排序方法。他不要求在接口上使用sort成员函数,而是在其他地方使用静态函数,将IList作为参数。对于那些实现IList的人来说,这不会增加复杂性。在C#中,“列表”通常在“集合”之上提供直接的元素索引,即简单地添加/删除元素。您可以使用合并排序对O(nlgn)中的链接列表进行排序。我实际上不知道有任何使用链接列表作为存储的IList
实现。特别是,stockLinkedList
类没有实现IList
。你能把这句话换成一个问题吗,也许“c#没有内置的IList排序和二进制搜索的原因吗?”现在你只是在发表一个声明,呼吁人们在微软的网站上投票支持它,它有被关闭的风险,因为spamIt是一种隐藏在漫无边际中的东西,但是有一个问题可以帮助我理解,如果微软故意忽略它,为什么它不存在:“他们故意忽略这个功能是有原因的吗?”stack overflow是一个问答网站。把更多的注意力放在你的问题上(特别是
IList<T> list = ...
list.Sort();
T huntFor = ...
int i = list.BinarySearch(huntFor);