How to Sort a List by a property in the object in C# ?

To sort a List<T> by a property of the objects in C#, you can use either the List.Sort method with a custom comparison or LINQ’s OrderBy to create a new sorted list. Here are the common approaches:

1. Using List.Sort with a Lambda Expression (In-Place Sort)

Sort the list in-place by specifying a comparison using a lambda:

// Sort by a property (e.g., Name) in ascending order
list.Sort((x, y) => x.Property.CompareTo(y.Property));

// Example for a 'Person' class with a 'Name' property
people.Sort((p1, p2) => p1.Name.CompareTo(p2.Name));

// Case-insensitive string comparison
people.Sort((p1, p2) => string.Compare(p1.Name, p2.Name, StringComparison.OrdinalIgnoreCase));

// Descending order
people.Sort((p1, p2) => p2.Age.CompareTo(p1.Age));

2. Using LINQ OrderBy (Creates a New List)

Create a new sorted list without modifying the original:

// Sort by a property in ascending order
var sortedList = list.OrderBy(x => x.Property).ToList();

// Example for 'Name' property
var sortedPeople = people.OrderBy(p => p.Name).ToList();

// Descending order with OrderByDescending
var sortedDescending = people.OrderByDescending(p => p.Age).ToList();

// Case-insensitive sorting
var caseInsensitiveSorted = people.OrderBy(p => p.Name, StringComparer.OrdinalIgnoreCase).ToList();

// Sort by multiple properties
var multiSorted = people.OrderBy(p => p.LastName).ThenBy(p => p.FirstName).ToList();

3. Using a Custom IComparer<T>

Create a reusable comparer for complex or repeated sorting logic:

public class AgeComparer : IComparer<Person>
{
    public int Compare(Person x, Person y) => x.Age.CompareTo(y.Age);
}

// Usage
people.Sort(new AgeComparer());

4. Generic Property Comparer (Advanced)

A reusable comparer that sorts by any property using a delegate:

public class PropertyComparer<T, TKey> : IComparer<T>
{
    private readonly Func<T, TKey> _keySelector;
    private readonly IComparer<TKey> _comparer;

    public PropertyComparer(Func<T, TKey> keySelector, IComparer<TKey> comparer = null)
    {
        _keySelector = keySelector;
        _comparer = comparer ?? Comparer<TKey>.Default;
    }

    public int Compare(T x, T y) => _comparer.Compare(_keySelector(x), _keySelector(y));
}

// Usage: Sort by 'Name' (case-sensitive)
people.Sort(new PropertyComparer<Person, string>(p => p.Name));

Key Considerations:

  • In-Place vs. New List: Use List.Sort for in-place sorting and LINQ for a new sorted list.
  • Case Sensitivity: Use StringComparer (e.g., StringComparer.OrdinalIgnoreCase) for string properties.
  • Performance: List.Sort is generally faster for large lists, while LINQ offers readability and flexibility.

Choose the method that best fits your scenario based on whether you need to modify the original list, handle complex sorting, or prioritize readability.

Leave a Reply

Your email address will not be published. Required fields are marked *