Reputation: 1593
I have came up with a function that orders a list by a specified value and then returns a new object value. Where I am stuck is in the .Select
statement when trying to get the StatValue
. The current example below is what I am trying to do (which obviously doesnt work)
I can get a string value of the passed in order by property, I need to use this property string when getting the StatValue
i.e x.GoalsPerGame
private static TodayStatsItem GetStatsValue<TOrderBy>(Expression<Func<PlayerItem, bool>> filter,
Expression<Func<PlayerItem, TOrderBy>> orderBy, IEnumerable<PlayerItem> items, string desc)
{
var itemSorted = new TodayStatsItem {
PlayerItems = items.AsQueryable().OrderBy(orderBy).Select(x => new TodayStatsViewModel
{
Name = x.Name,
//StatValue = ((MemberExpression)orderBy.Body).Member.Name.ToString() // returns GoalsPerGame
StatValue = x.((MemberExpression)orderBy.Body).Member.Name.ToString() // attempt to access property
}),
StatName = desc
};
return itemSorted;
}
The call to this method would looks like this.
this.LeagueItem.Add(GetStatsValue(null, x => x.GoalsPerGame, this.GameReport, "Goals Per Game"));
Is this any way to accomplish this? Thanks.
Upvotes: 1
Views: 1239
Reputation: 2877
Here's a method for getting the property value from an object with the specified property name using reflection:
using System.Reflection;
public static object GetPropertyValue(object obj, string propertyName)
{
PropertyInfo property = obj.GetType().GetProperty(propertyName);
return property.GetValue(obj);
}
In your case:
string propertyName = ((MemberExpression)orderBy.Body).Member.Name.ToString();
StatValue = (int)GetPropertyValue(x, propertyName); // I'm assuming StatValue is of type int
But to achieve what you are trying to do, you could first compile the orderBy
expression and then use it to get the value, which is faster than reflection.
Like this:
private static TodayStatsItem GetStatsValue<TOrderBy>(Expression<Func<PlayerItem, bool>> filter,
Expression<Func<PlayerItem, TOrderBy>> orderBy, IEnumerable<PlayerItem> items, string desc)
{
Func<PlayerItem, TOrderBy> orderByDeleg = orderBy.Compile();
var itemSorted = new TodayStatsItem {
PlayerItems = items.AsQueryable().OrderBy(orderByDeleg).Select(x => new TodayStatsViewModel
{
Name = x.Name,
StatValue = orderByDeleg(x)
}),
StatName = desc
};
return itemSorted;
}
Upvotes: 2