linq сортировка списка по булевым полям
Имеется тестовый класс:
public class TestData
{
public bool IsImportant { get; set; }
public bool IsImportant1 { get; set; }
public bool IsImportant2 { get; set; }
public string Data { get; set; }
}
P.S заранее прошу не придираться к неймингу )
Я создаю список объектов TestData , и мне нужно сортировать по полям IsImportant или IsImportant1 или IsImportant2
// Add data to the list.
var items = new List<TestData>();
items.Add(new TestData() { IsImportant = true, Data = "Bird" });
items.Add(new TestData() { IsImportant1 = true, Data = "Cat" });
items.Add(new TestData() { IsImportant2 = true, Data = "Human" });
// Sort by bool on class.
var sorted = items.OrderBy(x => x.IsImportant1).ToArray();
// Put "important" items first.
foreach (var item in sorted)
{
Console.WriteLine( $"{ item.Data} ; {item.IsImportant}; {item.IsImportant1}; { item.IsImportant2}");
}
Результат вывода :
Bird ; True; False; False
Human ; False; False; True
Cat ; False; True; False
Вопрос , почему не сортирует по полю IsImportant1? По идее первым должен быть Cat ? Как сделать так чтобы первым в списке выводился Cat. Просто у меня есть метод который будет в зависимости от параметра сортировать по определенному полю список объектов и выводить его.
Ответы (1 шт):
Интерфейс IComparable<T> для булевого типа реализован так, что значение False меньше (дословно – "в порядке сортировки находится до") True. Исходный код структуры Boolean:
public int CompareTo(Boolean value) { if (m_value==value) { return 0; } else if (m_value==false) { return -1; } return 1; }
Поэтому в вашем примере Cat идет последним – значение его свойства IsImportant1, по которому вы проводите сортировку, равно True.
Если вам нужно изменить поведение на противоположное – можно вместо
var sorted = items.OrderBy(x => x.IsImportant1).ToArray();
написать:
var sorted = items.OrderByDescending(x => x.IsImportant1).ToArray();
Также, можете раскрыть выборку ключа сортировки более явно для себя, например так:
items.OrderBy(x => x.IsImportant1 == false ? 0 : 1); // False будут идти раньше True
items.OrderBy(x => x.IsImportant1 == true ? 0 : 1); // True будут идти раньше False