Ответ 1
//Assuming all the fields implement IComparable
int result = a.field1.CompareTo(b.field1);
if (result == 0)
result = a.field2.CompareTo(b.field2);
if (result == 0)
result = a.field3.CompareTo(b.field3);
return result;
У меня есть класс person с тремя полями: Title, Name, Gender, и я хотел бы создать Custom Sort для его сортировки сначала по заголовку, затем по имени, а затем по полу по возрастанию:
public class SortPerson : IComparer
{
public int Compare(object x, object y)
{
(…)
}
}
Я знаю, как это сделать для сравнения только одной переменной: Но как мне приступить к трем?
public class SortPerson : IComparer
{
int IComparer.Compare(object a, object b)
{
Person p1=(Person)a;
Person p2=(Person)b;
if (p1.Title > p2.Title)
return 1;
if (p1.Title < p2.Title)
return -1;
else
return 0;
}
}
Большое спасибо,
//Assuming all the fields implement IComparable
int result = a.field1.CompareTo(b.field1);
if (result == 0)
result = a.field2.CompareTo(b.field2);
if (result == 0)
result = a.field3.CompareTo(b.field3);
return result;
Я не знаю, какое использование у вас есть для сравнения, но, возможно, вместо сравнения можно использовать оператор "order by" LINQ, который позволяет сортировать по различным полям:
var orderedListPersons =
from p in listPersons
orderby p.Title, p.Name, p.Gender
select person;
будет заказывать listPersons так, как вы хотите. Вы также можете использовать методы LINQ OrderBy и ThenBy для одного и того же с другим синтаксисом:
var orderedlistPersons = listPersons.OrderBy(p => p.Title).ThenBy(p => p.Name).ThenBy(p => p.Gender);
Сортировка по одному полю в порядке очередности, только продолжение следующего поля, если предыдущее сравнение полей привело к 0 (поля равны). Для примера сортировки по 2-мя полям см. Следующее.
http://csharp.2000things.com/2010/10/30/135-implementing-icomparable-to-allow-sorting-a-custom-type/
Одним из способов было бы реализовать такой интерфейс.
public class Person : IComparer<Person>
{
public string Titel { get; set; }
int IComparer<Person>.Compare(Person x, Person y)
{
if (x is null)
throw new ArgumentNullException(nameof(x));
if (y is null)
throw new ArgumentNullException(nameof(y));
return x.Titel.CompareTo(y.Titel);
}
}
Иногда вы можете иметь немного больше контроля над тем, как бы вы хотели сортировать. Конечно, вы можете использовать linq, однако тогда вам придется потерять скорость выделения мусора из списка, и это не сложно сделать при реализации интерфейса IComparer.
Посмотрите на приведенный ниже пример, и вы увидите, что вы можете комбинировать столько свойств, сколько вам нужно.
public class Person : IComparable<Person>, IComparer<Person>
{
public string Titel { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? SomeOptionalValue { get; set; }
int IComparer<Person>.Compare(Person x, Person y)
{
return (x as IComparable).CompareTo(y);
}
int IComparable<Person>.CompareTo(Person other)
{
if (other is null)
throw new ArgumentNullException(nameof(other));
int result = this.Titel.CompareTo(other.Titel);
//chain the other properties in the order you'd like to
//have them sorted.
if (result == 0)
result = this.FirstName.CompareTo(other.FirstName);
if (result == 0)
result = this.LastName.CompareTo(other.LastName);
//use optional values as well as call the compare implementation on a class
if (result == 0 && SomeOptionalValue.HasValue && other.SomeOptionalValue.HasValue)
result = DateTime.Compare(this.SomeOptionalValue.Value, other.SomeOptionalValue.Value);
return result;
}
}