Reputation: 481
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();
}
Upvotes: 1
Views: 2246
Reputation: 19574
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();
}
Upvotes: 1
Reputation: 354
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);
}
Upvotes: 2