我希望创建一种动态方式,通过参数xy返回排序列表。列表可以按降序,升序,按ID,用户名,邮件等排序。
我以字符串形式接收此参数。例如sort=-username
减号表示列表下降。而sort参数是用户名。
所以我返回user.OrderByDescending(o => o.Username).ToList();
此时借助长if-else结构,我可以检测出需要哪种排序。
我希望我可以借助函数将sort字符串参数替换为object参数。
伪代码
//input for example: sort=-username
Boolean isAscending = isAscending(sort) //return true or false
var parameter = isSortStringInsideObject(sort) //
if (isAscending) {
user.OrderBy(o => o.parameter).ToList();
} else {
user.OrderByDescending(o => o.parameter).ToList();
}
因此参数可以是对象中的每个参数。
我是.net核心新手。所以我希望我没有制定一个乌托邦式的要求。
答案 0 :(得分:4)
这样的事情可以解决问题(使用反射):
var isAscending = GetIsAscending(sort);
var pi = typeof(User).GetProperty(parameter);
if (pi != null)
user = isAscending
? user.OrderBy(a => pi.GetValue(a, null))
: user.OrderByDescending(a => pi.GetValue(a, null));
答案 1 :(得分:0)
我尝试保持输入并使用带有字符串的地图来显示func,这样您就可以查找进入的值并将其映射。
var list = new List<Item> { new Item() { Name = "aob", Age = 11 }, new Item() {Name = "bob", Age = 10},};
var input = "-name";
var map = new Dictionary<string, Func<Item, object>>()
{
{"name", x => x.Name},
{"age", x => x.Age}
};
if (input.StartsWith('-'))
{
var orderby = map[input.Substring(1)];
var orderedEnumerable = list.OrderByDescending(orderby);
}
else
{
var orderby = map[input];
var orderedEnumerable = list.OrderBy(orderby);
}
答案 2 :(得分:0)
有趣..使用System.Linq.Expression命名空间动态创建传递给Order或OrderByDescending的func也是相关的,特别是如果需要许多可能的排序参数。
E.g。在我们有一个字符串参数
之后var parameter = isSortStringInsideObject(sort)
可以构造这样的函数(T是用户的类型):
Dictionary<string, PropertyInfo> properties = typeof(T).GetProperties().ToDictionary(pi => pi.Name);
ParameterExpression parameterExpression = Expression.Parameter(typeof(T));
Expression expression = Expression.MakeMemberAccess(parameterExpression, properties[parameter]);
Func<T, string> orderFunc = Expression.Lambda<Func<T, string>>(expression, parameterExpression).Compile();
看起来有点沉重:)但它可能有效。