دات نت 7 به همراه دو متد جدید Order و OrderDescending است که مرتب سازی مجموعههای ساده را انجام میدهند.
روش متداول مرتب سازی مجموعههای ساده تا پیش از دات نت 7
فرض کنید لیستی از اعداد را داریم:
var numbers = new List<int> { -7, 1, 5, -6 };
تا پیش از دات نت 7 با استفاده از متدهای OrderBy و OrderByDescending موجود به همراه LINQ، امکان مرتب سازی صعودی و نزولی این لیست وجود دارد:
var sortedNumbers1 = numbers.OrderBy(n => n);
var sortedNumbers2 = numbers.OrderByDescending(n => n);
که در اینجا ذکر پارامتر keySelector ضروری است:
public static IOrderedEnumerable<TSource> OrderBy<TSource,TKey>(
[NotNull] this IEnumerable<TSource> source,
[NotNull] Func<TSource,TKey> keySelector)
هرچند میشد طراحی آن سادهتر باشد و حداقل برای مجموعههای ساده، نیازی به ذکر آن نباشد.
روش جدید مرتب سازی مجموعههای ساده در دات نت 7
دات نت 7 به همراه دو متد جدید Order و OrderDescending است که دیگر نیازی به ذکر پارامتر keySelector ذکر شده را ندارند:
var sortedNumbers3 = numbers.Order();
var sortedNumbers4 = numbers.OrderDescending();
و امضای آنها به صورت زیر است:
public static IOrderedEnumerable<T> Order<T>(this IEnumerable<T> source)
public static IOrderedEnumerable<T> OrderDescending<T>(this IEnumerable<T> source)
که در حقیقت دو متد الحاقی جدید قابل اعمال بر روی انواع و اقسام IEnumerableها هستند.
در مورد سایر مجموعههای پیچیده چطور؟
فرض کنید کلاس User را:
public class User
{
public string Name { set; get; }
public int Age { set; get; }
}
به همراه لیستی از آن تعریف کردهایم:
List<User> users = new()
{
new User { Name = "User 1", Age = 34 },
new User { Name = "User 2", Age = 24 },
};
سؤال: آیا اگر متد Order را بر روی این لیست فراخوانی کنیم:
var orderedUsers = users.Order();
برای مثال این مجموعه بر اساس نام و سن مرتب خواهد شد؟ که پاسخ آن خیر است و همچنین استثنائی را صادر میکند بر این مبنا که باید کلاس User، اینترفیس IComparable را پیاده سازی کند تا بتوان آنها را مقایسه کرد؛ برای مثال چیزی شبیه به تغییرات زیر:
public class User : IComparable<User>
{
public string Name { set; get; }
public int Age { set; get; }
public int CompareTo(User? other)
{
if (ReferenceEquals(this, other))
{
return 0;
}
if (ReferenceEquals(null, other))
{
return 1;
}
var nameComparison = string.Compare(Name, other.Name, StringComparison.Ordinal);
if (nameComparison != 0)
{
return nameComparison;
}
return Age.CompareTo(other.Age);
}
}
که در یک چنین مواردی شاید بهتر باشد از همان متد OrderBy پیشین استفاده کرد که الزامی به پیاده سازی اینترفیس IComparable را ندارد:
var orderedUsers2 = users.OrderBy(user => user.Name).ThenBy(user => user.Age);