@DavidMills가 받아 들인 대답은 꽤 좋지만 개선 될 수 있다고 생각합니다. 하나의 ComparisonComparer<T>
경우 프레임 워크에 이미 정적 메서드가 포함되어있는 경우 클래스 를 정의 할 필요가 없습니다 Comparer<T>.Create(Comparison<T>)
. 이 메서드는 IComparison
즉석 에서 생성하는 데 사용할 수 있습니다 .
또한, 캐스트 IList<T>
에 IList
어떤 위험 할 수있는 잠재력을 가지고있다. 내가 본 대부분의 경우 List<T>
어떤 구현 IList
이을 구현 하는 데 백그라운드에서 사용 IList<T>
되지만 이는 보장되지 않으며 부서지기 쉬운 코드로 이어질 수 있습니다.
마지막으로 오버로드 된 List<T>.Sort()
메서드에는 4 개의 서명이 있으며 그중 2 개만 구현됩니다.
List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
아래 클래스 List<T>.Sort()
는 IList<T>
인터페이스에 대한 4 개의 서명을 모두 구현합니다 .
using System;
using System.Collections.Generic;
public static class IListExtensions
{
public static void Sort<T>(this IList<T> list)
{
if (list is List<T>)
{
((List<T>)list).Sort();
}
else
{
List<T> copy = new List<T>(list);
copy.Sort();
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
{
if (list is List<T>)
{
((List<T>)list).Sort(comparison);
}
else
{
List<T> copy = new List<T>(list);
copy.Sort(comparison);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, IComparer<T> comparer)
{
if (list is List<T>)
{
((List<T>)list).Sort(comparer);
}
else
{
List<T> copy = new List<T>(list);
copy.Sort(comparer);
Copy(copy, 0, list, 0, list.Count);
}
}
public static void Sort<T>(this IList<T> list, int index, int count,
IComparer<T> comparer)
{
if (list is List<T>)
{
((List<T>)list).Sort(index, count, comparer);
}
else
{
List<T> range = new List<T>(count);
for (int i = 0; i < count; i++)
{
range.Add(list[index + i]);
}
range.Sort(comparer);
Copy(range, 0, list, index, count);
}
}
private static void Copy<T>(IList<T> sourceList, int sourceIndex,
IList<T> destinationList, int destinationIndex, int count)
{
for (int i = 0; i < count; i++)
{
destinationList[destinationIndex + i] = sourceList[sourceIndex + i];
}
}
}
용법:
class Foo
{
public int Bar;
public Foo(int bar) { this.Bar = bar; }
}
void TestSort()
{
IList<int> ints = new List<int>() { 1, 4, 5, 3, 2 };
IList<Foo> foos = new List<Foo>()
{
new Foo(1),
new Foo(4),
new Foo(5),
new Foo(3),
new Foo(2),
};
ints.Sort();
foos.Sort((x, y) => Comparer<int>.Default.Compare(x.Bar, y.Bar));
}
여기서 아이디어는 List<T>
가능한 한 정렬을 처리하기 위해 기본 기능을 활용하는 것입니다 . 다시 말하지만, IList<T>
내가 본 대부분의 구현은 이것을 사용합니다. 기본 컬렉션이 다른 유형 인 List<T>
경우 입력 목록의 요소를 사용하여 새 인스턴스를 만드는 것으로 대체하고 이를 사용하여 정렬 한 다음 결과를 다시 입력 목록에 복사합니다. 이는 입력 목록이 IList
인터페이스를 구현하지 않는 경우에도 작동합니다 .