摘自:https://www.cnblogs.com/wintertone/p/12021166.html
C#里List.Sort的用法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ListSort
{
class Program
{
static void Main(string[] args)
{
List<C> L = new List<C>();
L.Add(new C { n = 1, s = "b" });
L.Add(new C { n = 3, s = "a" });
L.Add(new C { n = 2, s = "c" });<br>
// 方法1 使用Comparison<T>委托。
L.Sort((left, right) =>
{
if (left.n > right.n)
return 1; //right在前,left在后
else if (left.n == right.n)
return 0;
else
return -1;
});
// 方法2 使用IComparer<T>接口。
L.Sort(new CComparer());
// 方法3 除以上两种方法以外还可以使用另一种方法,在C类中实现IComparable<T>
L.Sort();
}
}
//方法二
public class CComparer : IComparer<C>
{
public int Compare(C left, C right)
{
if (left.n > right.n)
return 1;
else if (left.n == right.n)
return 0;
else
return -1;
}
}
//方法三
public class C : IComparable<C>
{
public int n;
public string s;
public int CompareTo(C other)
{
if (this.n > other.n)
return 1;
else if (this.n == other.n)
return 0;
else
return -1;
}
}
}
填坑
- Comparison在使用时也会先转化成IComparer,所以是一样的。
- 需要注意的是,IComparer的实现一定要有返回0的情况(即相等时),因为在sort时会出现和自身的比较
//List<T>.Sort:
[__DynamicallyInvokable]
public void Sort(Comparison<T> comparison)
{
if (comparison == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
if (this._size <= 0)
return;
Array.Sort<T>(this._items, 0, this._size, (IComparer<T>) new Array.FunctorComparer<T>(comparison)); //将comparison转为IComparer
}
//Array.Sort<T>:
[SecuritySafeCritical]
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[__DynamicallyInvokable]
public static void Sort<T>(T[] array, int index, int length, IComparer<T> comparer)
{
if (array == null)
throw new ArgumentNullException(nameof (array));
if (index < 0 || length < 0)
throw new ArgumentOutOfRangeException(length < 0 ? nameof (length) : nameof (index), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - index < length)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
if (length <= 1 || (comparer == null || comparer == Comparer<T>.Default) && Array.TrySZSort((Array) array, (Array) null, index, index + length - 1))
return;
ArraySortHelper<T>.Default.Sort(array, index, length, comparer);
}
//ArraySortHelper<T>.Sort:
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
try
{
if (comparer == null)
comparer = (IComparer<T>) Comparer<T>.Default;
if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)//这是干啥的???
ArraySortHelper<T>.IntrospectiveSort(keys, index, length, comparer);
else
ArraySortHelper<T>.DepthLimitedQuickSort(keys, index, length + index - 1, comparer, 32); //List用的是快排
}
catch (IndexOutOfRangeException ex)
{
IntrospectiveSortUtilities.ThrowOrIgnoreBadComparer((object) comparer);
}
catch (Exception ex)
{
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_IComparerFailed"), ex);
}
}
//ArraySortHelper<T>.DepthLimitedQuickSort
internal static void DepthLimitedQuickSort(T[] keys, int left, int right, IComparer<T> comparer, int depthLimit)
{
while (depthLimit != 0)
{
int index1 = left;
int index2 = right;
int index3 = index1 + (index2 - index1 >> 1);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index1, index3);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index1, index2);
ArraySortHelper<T>.SwapIfGreater(keys, comparer, index3, index2);
T key1 = keys[index3];
do
{
while (comparer.Compare(keys[index1], key1) < 0)
++index1;
while (comparer.Compare(key1, keys[index2]) < 0)
--index2;
if (index1 <= index2)
{
if (index1 < index2)
{
T key2 = keys[index1];
keys[index1] = keys[index2];
keys[index2] = key2;
}
++index1;
--index2;
}
else
break;
}
while (index1 <= index2);
--depthLimit;
if (index2 - left <= right - index1)
{
if (left < index2)
ArraySortHelper<T>.DepthLimitedQuickSort(keys, left, index2, comparer, depthLimit);
left = index1;
}
else
{
if (index1 < right)
ArraySortHelper<T>.DepthLimitedQuickSort(keys, index1, right, comparer, depthLimit);
right = index2;
}
if (left >= right)
return;
}
ArraySortHelper<T>.Heapsort(keys, left, right, comparer);
}