使用反射C#

时间:2017-05-11 11:02:39

标签: c# linq generics expression

我想出了一个按指定值排序列表的函数,然后返回一个新的对象值。在尝试获取Select时,我被困在。StatValue语句中。下面的当前示例是我正在尝试做的事情(显然不起作用)

我可以获取按属性传递的字符串值,我需要在获取StatValue时使用此属性字符串,即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;
}

对此方法的调用如下所示。

this.LeagueItem.Add(GetStatsValue(null, x => x.GoalsPerGame, this.GameReport, "Goals Per Game"));

这有什么办法可以实现这个目标吗?感谢。

1 个答案:

答案 0 :(得分:2)

这是使用反射从具有指定属性名称的对象获取属性值的方法:

using System.Reflection;

public static object GetPropertyValue(object obj, string propertyName)
{
    PropertyInfo property = obj.GetType().GetProperty(propertyName);
    return property.GetValue(obj);
}

在你的情况下:

string propertyName = ((MemberExpression)orderBy.Body).Member.Name.ToString();
StatValue = (int)GetPropertyValue(x, propertyName); // I'm assuming StatValue is of type int

但要实现您要做的事情,您可以先compile orderBy表达式,然后使用它来获取值,这比反射更快。

像这样:

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;
}