Следует иметь в виду, что Вам не нужен стабильный вид при сравнении всех участников. 2,0 решения, согласно просьбе, могут быть похожими на это:
public void SortList() {
MyList.Sort(delegate(MyClass a, MyClass b)
{
int xdiff = a.x.CompareTo(b.x);
if (xdiff != 0) return xdiff;
else return a.y.CompareTo(b.y);
});
}
Действительно отмечают, что эти 2,0 решения все еще предпочтительны по популярным 3.5 решениям Linq, они выполняют оперативный вид и не имеют O (n) требованием устройства хранения данных подхода Linq. Если Вы не предпочитаете, чтобы исходный Объект списка был нетронутым, конечно.
Для версий.Net, где можно использовать LINQ OrderBy
и ThenBy
(или ThenByDescending
в случае необходимости):
using System.Linq;
....
List<SomeClass>() a;
List<SomeClass> b = a.OrderBy(x => x.x).ThenBy(x => x.y).ToList();
<час> Примечание: для.Net 2.0 (или если Вы не можете использовать LINQ) см. ответ Hans Passant к этому вопросу.
Необходимо реализовать интерфейс IComparer. Вот хорошее сообщение с примером кода.
Прием должен реализовать стабильный вид. Я создал класс Виджета, который может содержать Ваши данные тестирования:
public class Widget : IComparable
{
int x;
int y;
public int X
{
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
public Widget(int argx, int argy)
{
x = argx;
y = argy;
}
public int CompareTo(object obj)
{
int result = 1;
if (obj != null && obj is Widget)
{
Widget w = obj as Widget;
result = this.X.CompareTo(w.X);
}
return result;
}
static public int Compare(Widget x, Widget y)
{
int result = 1;
if (x != null && y != null)
{
result = x.CompareTo(y);
}
return result;
}
}
я реализовал IComparable, таким образом, он может быть нестабильно отсортирован по Списку. Вид ().
Однако я также реализовал статический метод, Выдерживают сравнение, который может быть передан как делегат в методе поиска.
я одолжил этот метод сортировки вставки от C# 411:
public static void InsertionSort<T>(IList<T> list, Comparison<T> comparison)
{
int count = list.Count;
for (int j = 1; j < count; j++)
{
T key = list[j];
int i = j - 1;
for (; i >= 0 && comparison(list[i], key) > 0; i--)
{
list[i + 1] = list[i];
}
list[i + 1] = key;
}
}
Вы поместили бы это в класс помощников вида, который Вы упомянули в своем вопросе.
Теперь, для использования его:
static void Main(string[] args)
{
List<Widget> widgets = new List<Widget>();
widgets.Add(new Widget(0, 1));
widgets.Add(new Widget(1, 1));
widgets.Add(new Widget(0, 2));
widgets.Add(new Widget(1, 2));
InsertionSort<Widget>(widgets, Widget.Compare);
foreach (Widget w in widgets)
{
Console.WriteLine(w.X + ":" + w.Y);
}
}
И это производит:
0:1
0:2
1:1
1:2
Press any key to continue . . .
Это могло, вероятно, быть очищено с некоторыми анонимными делегатами, но я оставлю это до Вас.
РЕДАКТИРОВАНИЕ : И NoBugz демонстрирует питание анонимных методов... так, считайте мой большим количеством oldschool: P