对IList排序的最佳方法是什么<;T>;在.NET2.0中?
我有一个需要排序的对IList排序的最佳方法是什么<;T>;在.NET2.0中?,.net,.net-2.0,.net,.net 2.0,我有一个需要排序的IList,如果可能的话,我宁愿不复制列表。我注意到,ArrayList有一个Adapter静态方法,它包装传递的列表而不复制它,但是这需要一个IList,我有一个IList。从System.Collections.Generic.IList转换为System.Collections.IList并使用Adapter方法是否安全 请注意,这是.Net 2.0,因此LINQ不是一个选项。在Paul Fox的博客中,我推荐“如何对IList排序”一文: 为了以防万一,我将把这篇文章复
IList
,如果可能的话,我宁愿不复制列表。我注意到,ArrayList
有一个Adapter
静态方法,它包装传递的列表而不复制它,但是这需要一个IList
,我有一个IList
。从System.Collections.Generic.IList转换为System.Collections.IList
并使用Adapter
方法是否安全
请注意,这是.Net 2.0,因此LINQ不是一个选项。在Paul Fox的博客中,我推荐“如何对IList排序”一文:
为了以防万一,我将把这篇文章复制到这里:
如何对通用IList进行排序
更新
您可以阅读并更新有关的帖子。许多人会喜欢更新后的帖子中提到的方法
对泛型IList进行排序
我试图对一个通用的IList进行排序,并找到了一个相当简单的方法
第一步
您需要为IList中包含的类型实现IComparable。对于这个例子,我将使用一种简单的语言Dto类
public class LanguageDto : IComparable {
private String name;
public string Name { get { return name; } set { name = value; } }
public LanguageDto(string name) {
this.name = name;
}
#region IComparable Members
public int CompareTo(object obj) {
if (obj is LanguageDto) {
LanguageDto language = (LanguageDto)obj;
return this.name.CompareTo(language.name);
}
throw new ArgumentException(string.Format("Cannot compare a LanguageDto to an {0}", obj.GetType().ToString()));
}
#endregion
}
步骤2
把你的行李分类。为此,将使用ArrayList.Adapter()方法传入IList,然后调用Sort方法。就像这样
ArrayList.Adapter((IList)languages).Sort();
注:语言类型为“IList”
然后,语言应该是您类型的排序列表 不能将IList(T)强制转换为IList
使用Reflector进行嗅探后,ArrayList.Adapter(IList).Sort()将首先将列表复制到对象数组,对数组进行排序,然后将数组复制回列表:
object[] array = new object[count];
this.CopyTo(index, array, 0, count);
Array.Sort(array, 0, count, comparer);
for (int i = 0; i < count; i++)
{
this._list[i + index] = array[i];
}
object[]数组=新对象[count];
this.CopyTo(索引、数组、0、计数);
排序(数组,0,计数,比较器);
for(int i=0;i
如果列表中的T(T)是值类型,则可能会产生装箱开销
如果需要更改列表中对象的顺序,可以采用类似方法:
IList<object> unsorted = ...
List<object> sorted = new List<object>(unsorted);
sorted.Sort();
for (int i = 0; i < unsorted.Countt; i++)
{
unsorted[i] = sorted[i];
}
IList unsorted=。。。
已排序列表=新列表(未排序);
sorted.Sort();
for(int i=0;i
如果列表太大(如数亿项),您无法在内存中创建额外的副本,我建议您首先使用列表(T)或实现您最喜欢的就地排序算法。我知道它不是.NET 2.0,但我非常喜欢LINQ,并会尽可能支持它:)
IList<object> unsorted = ...
IList<object> sortedList = unsorted.Orderby(x => x.Tostring()).Tolist();
简单排序:
var sortedProducts =
from p in products
orderby p.ProductName
select p;
ObjectDumper.Write(sortedProducts);
string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
var sortedDigits =
from d in digits
orderby d.Length, d
select d;
按多个条件排序:
var sortedProducts =
from p in products
orderby p.ProductName
select p;
ObjectDumper.Write(sortedProducts);
string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
var sortedDigits =
from d in digits
orderby d.Length, d
select d;
两个例子都来自
,因为排序方法不在ILIST接口上,您可以考虑创建自己的:
interface ISortableList<T> : IList<T>
{
void Sort();
void Sort(IComparer<T> comparer);
}
class SortableList<T> : List<T>, ISortableList<T> { }
/* usage */
void Example(ISortedList<T> list)
{
list.Sort();
list.Sort(new MyCustomerComparer());
}
接口可移植列表:IList
{
无效排序();
无效排序(IComparer比较器);
}
类SortableList:List,ISortableList{}
/*用法*/
无效示例(ISortedList列表)
{
list.Sort();
排序(新的MyCustomerComparer());
}
通常,在方法中指定的参数类型应该是实际需要调用的成员的最小公分母。如果您确实需要调用Sort()方法,那么您的参数应该定义该成员。否则,您可能应该将其加载到另一个可以做您想做的事情的对象中,例如:
void Example(IList<T> list)
{
list = new List<T>(list).Sort();
}
void示例(IList列表)
{
list=新列表(list.Sort();
}
这实际上应该非常快,几乎可以肯定比编写自己的自定义内联排序算法还要快。IList unsorted=。。。
IList<object> unsorted = ...
IList<object> sortedList = unsorted.Orderby(x => x.Tostring()).Tolist();
IList sortedList=unsorted.Orderby(x=>x.Tostring()).Tolist();
这将在对象的特定字段上提供排序列表。如果需要对不同类的列表(而不是ILists)进行排序,而不需要为所有类创建单独的比较器类,并且仍然保持实体类的干净(您不希望实现IComparable),则可以使用以下选项(与.NET 2.0兼容):
公共类动态比较程序:IComparer
{
私有函数计算函数;
专用多路复用器;
私有函数比较函数;
公共动态比较程序(Func calculateFunc,bool reverse=false)
{
if(calculateFunc==null)
{
抛出新异常(“委托函数'calculateFunc'不能为null”);
}
this.calculateFunc=calculateFunc;
这个.calculateMultiplier=反向?-1:1;
this.compareFunc=null;
}
公共动态比较程序(Func compareFunc)
{
if(calculateFunc==null)
{
抛出新异常(“委托函数'compareFunc'不能为null”);
}
this.calculateFunc=null;
this.compareFunc=compareFunc;
}
公共整数比较(TX,TY)
{
if(calculateFunc!=null)
{
return(calculateFunc(x)-calculateFunc(y))*this.calculateMultiplier;
}
if(compareFunc!=null)
{
返回compareFunc(x,y);
}
抛出新异常(“不可能进行比较,因为未指定比较或计算函数。”);
}
}
如果您使用的是.NET 2.0(可在上找到),则还需要Func委托:
public委托TResult Func(T);
公共代表TResult Func(T,U);
用法:
myList.Sort(new DynamicComparer<MyClass>(x => x.MyIntProperty) // Ascending
myList.Sort(new DynamicComparer<MyClass>(x => x.MyIntProperty, true) // Descending
myList.Sort(新的DynamicComparer(x=>x.MyIntProperty)//升序
排序(新的DynamicComparer(x=>x.MyIntProperty,true)//降序
一些简单的单元测试:
[TestClass()]
public class DynamicComparerTU
{
[TestMethod()]
public void SortIntList()
{
// Arrange
dynamic myIntArray = new int[] {
4,
1,
9,
0,
4,
7
};
dynamic myIntList = new List<int>(myIntArray);
// Act
int temp = 0;
for (int write = 0; write <= myIntArray.Length - 1; write++)
{
for (int sort = 0; sort <= myIntArray.Length - 2; sort++)
{
if (myIntArray(sort) > myIntArray(sort + 1))
{
temp = myIntArray(sort + 1);
myIntArray(sort + 1) = myIntArray(sort);
myIntArray(sort) = temp;
}
}
}
myIntList.Sort(new DynamicComparer<int>(x => x));
// Assert
Assert.IsNotNull(myIntList);
Assert.AreEqual(myIntArray.Length, myIntList.Count);
for (int i = 0; i <= myIntArray.Length - 1; i++)
{
Assert.AreEqual(myIntArray(i), myIntList(i));
}
}
[TestMethod()]
public void SortStringListByLength()
{
// Arrange
dynamic myStringArray = new string[] {
"abcd",
"ab",
"abcde",
"a",
"abc"
};
dynamic myStringList = new List<string>(myStringArray);
// Act
myStringList.Sort(new DynamicComparer<string>(x => x.Length));
// Assert
Assert.IsNotNull(myStringList);
Assert.AreEqual(5, myStringList.Count);
Assert.AreEqual("a", myStringList(0));
Assert.AreEqual("ab", myStringList(1));
Assert.AreEqual("abc", myStringList(2));
Assert.AreEqual("abcd", myStringList(3));
Assert.AreEqual("abcde", myStringList(4));
}
[TestMethod()]
public void SortStringListByLengthDescending()
{
// Arrange
dynamic myStringArray = new string[] {
"abcd",
"ab",
"abcde",
"a",
"abc"
};
dynamic myStringList = new List<string>(myStringArray);
// Act
myStringList.Sort(new DynamicComparer<string>(x => x.Length, true));
// Assert
Assert.IsNotNull(myStringList);
Assert.AreEqual(5, myStringList.Count);
Assert.AreEqual("abcde", myStringList(0));
Assert.AreEqual("abcd", myStringList(1));
Assert.AreEqual("abc", myStringList(2));
Assert.AreEqual("ab", myStringList(3));
Assert.AreEqual("a", myStringList(4));
}
}
[TestClass()]
公共类动态比较程序
{
[TestMethod()]
公共无效排序列表()
{
//安排
动态myIntArray=new int[]{
4.
1.
9,
0,
4.
7.
};
动态myIntList=新列表(myIntArray);
//表演
内部温度=0;
对于(int write=0;write x));
//断言
Assert.IsNotNull(myIntList);