1

I have a method where I pass in a List, which is then sorted in the method.

The type ChartItemData includes properties like Average, ProportionHighScore, and ProportionLowScore. Depending on method usage, I need to sort the List inside the method on different properties, and either Ascending or Descending.

How can I specify in the parameter list of the method which property to sort on, and which sortorder to use?

I imagine I could set up an Enum for SortDirection, but I still need to find out how to pass in the property to sort on. Here is some pseudocode to illustrate what I'm after, using List.OrderBy. I could also sort the List in place with the List.Sort method, if that makes more sense.

public enum SortDirection { Ascending, Descending }

public void myMethod(List<ChartItemData> myList, "parameter propertyToSortOn", 
    SortDirection direction)
{
     if (direction == SortDirection.Ascending)
        var sorted = ChartData.OrderBy(x => x."propertyToSortOn").ToList();
     else
        var sorted = ChartData.OrderByDescending(x => x."propertyToSortOn").ToList();
}
2

2 Answers 2

2

Would something like this work? It allows you to refer to the property to sort on through the second method parameter (a lambda). Otherwise you'd be pretty much stuck to reflection.

public class ChartItemData
    {
        public double Average { get; set; }
        public double HighScore { get; set; }
        public double LowScore { get; set; }

        public string Name { get; set; }
    }

    class Program
    {
        public enum SortDirection { Ascending, Descending }

        public void myMethod<T>(List<ChartItemData> myList, Func<ChartItemData, T> selector, SortDirection direction)
        {
            List<ChartItemData> sorted = null;

            if (direction == SortDirection.Ascending)
            {
                sorted = myList.OrderBy(selector).ToList();
            }
            else
            {
                sorted = myList.OrderByDescending(selector).ToList();
            }

            myList.Clear();
            myList.AddRange(sorted);
        }

        public void usage()
        {
            List<ChartItemData> items = new List<ChartItemData>();

            myMethod(items, x => x.Average, SortDirection.Ascending);
            myMethod(items, x => x.Name, SortDirection.Ascending);
        }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this looks good - and also nice that I got to try out and understand the "Method<T>" signature, which I haven't used before.
1

I'd say the easiest way would be to use reflection to get the PropertyInfo from the name provided.

You can then use that PropertyInfo to get the value from each value within the list to sort the list in the following way:

public List<ChartItemData> myMethod(List<ChartItemData> myList, string propName, SortDirection direction)
{
    var desiredProperty = typeof(ChartItemData).GetProperty(propName, BindingFlags.Public | BindingFlags.Instance);

    if (direction == SortDirection.Ascending)
        return myList.OrderBy(x => desiredProperty.GetValue(x)).ToList();
    else
        return myList.OrderByDescending(x => desiredProperty.GetValue(x)).ToList();
}

1 Comment

Very nice, this would work. I'll try it out in some scenarios. However, if I understand correctly, here I need to pass the property name as hardcoded, so presumably if I change property names I have to then also update the string code? I assume there's no Object.Property.PropertyNameToString()?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.