2

The following code snippet works fine.

switch (sortOrder)
{
    case "Group":
        list = list.OrderBy(o => o.Group).ToList();
        break;
    case "Company":
        list = list.OrderBy(o => o.Company).ToList();
        break;
    case "CurrencyId":
        list = list.OrderBy(o => o.CurrencyId).ToList();
        break;
    case "Field":
        list = list.OrderBy(o => o.Field).ToList();
        break; 
}

But i would like to write a more flexable code, not using a switch at all. Something like:

list = list.OrderBy(o => o.sortOrder).ToList();

How can I do this?

Shoshi S
  • 47
  • 7
  • http://stackoverflow.com/questions/2728340/how-can-i-do-an-orderby-with-a-dynamic-string-parameter – Paul Abbott Oct 15 '15 at 22:11
  • this is the best way actually. you can do it with reflection but i dont suggest you to do it. try to write efficient code instead of simplifying everything. – M.kazem Akhgary Oct 15 '15 at 22:14

3 Answers3

4

Using reflection is one alternative:

var sortOrder = "Group";

list = list.OrderBy(o => o.GetType().GetProperty(sortOrder).GetValue(o)).ToList();

Note that if you set "sortOrder" to a property name that doesn't actually exist in the class, you'll get a NullReferenceException. But if you're in control of the value, and not just accepting what a user types in (for example), then it'll be fine.

Grant Winney
  • 65,241
  • 13
  • 115
  • 165
2

You would have to use reflection. The problem is that reflection is slow and ugly.

list.OrderBy(o => o.GetType().GetProperty(sortOrder).GetValue(o)).ToList()

There's not much you can do about the performance. To make it look nicer you could put it into an extension method:

public static IEnumerable<T> OrderByPropertyName<T>(this IEnumerable<T> source, string propertyName)
{
    var property = typeof(T).GetProperty(propertyName);

    if (property == null) return source; // or throw exception
    else return source.OrderBy(x => property.GetValue(x));
}

Then use it as

list.OrderByPropertyName(sortOrder)

It works slightly faster than the first reflection approach, because GetProperty is only called once. You can also control the behavior if the property doesn't exist.

In my opinion, int this case switch is better than reflection.

Jakub Lortz
  • 14,616
  • 3
  • 25
  • 39
  • I used you answers slightly modified in a related Question. [here](https://stackoverflow.com/a/74703425/6560478). Feel free to edit attribution if needed. – Drag and Drop Dec 06 '22 at 13:45
0

The solution of @Jakub Lortz is quite good however there is more universal one.

public static IQueryable<T> OrderByPropertyName<T>(
    this IQueryable<T>source,
    string propertyName)
where T: YourClass
{
    // Here better to throw some exception
    if (propertyName == null) return source; 
    var property = typeof(T).GetProperty(propertyName);

    return source.OrderBy(x => property.GetValue(x));
}