【发布时间】:2017-05-11 11:02:38
【问题描述】:
我想出了一个函数,它按指定的值对列表进行排序,然后返回一个新的对象值。当我试图获取StatValue 时,我被困在 .Select 语句中。下面的当前示例是我正在尝试做的(显然不起作用)
我可以得到一个按属性顺序传递的字符串值,我在获取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"));
有什么方法可以做到这一点吗?谢谢。
【问题讨论】:
-
您应该能够(重新)使用给定的
orderBy表达式来获得所需的值(Compile().Invoke(item)- 尽管您可能只想编译一次并重用生成的函数)。据我所知,不需要反思。 -
你能举个例子吗?这也会比反射更有效吗?
-
orderBy.Compile()给你一个Func<PlayerItem, TOrderBy>。在您的示例中,这将是一个返回给定播放器项目的GoalsPerGame值的函数。因此,您只需在每个项目上调用该函数:StatValue = compiledOrderBy.Invoke(x)- 或只是StatValue = compiledOrderBy(x)。至于性能,反射往往涉及额外的检查,因此通常比较慢。 -
刚刚实现了这个,它也可以完美运行。现在我只需要决定哪个最适合该应用程序。感谢您的建议。
标签: c# linq generics expression