首页 / C# / c# – 列表顺序的动态链接
c# – 列表顺序的动态链接
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 列表顺序的动态链接,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3693字,纯文字阅读大概需要6分钟。
内容图文
![c# – 列表顺序的动态链接](/upload/InfoBanner/zyjiaocheng/808/01df3febc2d04b919d53541fa081cc74.jpg)
参见英文答案 > Dynamic LINQ OrderBy on IEnumerable
我正在编写一个列表排序扩展方法.
我的输入是列表和带有属性名称和排序方向的字符串.
这个字符串可以有多个属性,如下所示:
“命名ASC,日期DESC”等
我已经实现了字符串解析并使用了反射来从字符串中获取属性本身,但我现在所困扰的是如何动态链接orderby方法.
就像是:
_list.orderBy(x => x.prop1).thenBy(x => x.prop2)等
有没有办法动态构建它?
解决方法:
使用反射从字符串属性名称获取到PropertyInfo.然后,您可以使用PropertyInfo构建表达式树,以动态构建所有orderbys.获得表达式树后,将其编译为委托,(比如Func,IEnumerable>)将_list参数传递给此委托,它将为您提供另一个可枚举的有序结果.
要获取Enumerable上泛型方法的反射信息,请查看此帖子的答案:
Get a generic method without using GetMethods
public static class Helper
{
public static IEnumerable<T> BuildOrderBys<T>(
this IEnumerable<T> source,
params SortDescription[] properties)
{
if (properties == null || properties.Length == 0) return source;
var typeOfT = typeof (T);
Type t = typeOfT;
IOrderedEnumerable<T> result = null;
var thenBy = false;
foreach (var item in properties
.Select(prop => new {PropertyInfo = t.GetProperty(prop.PropertyName), prop.Direction}))
{
var oExpr = Expression.Parameter(typeOfT, "o");
var propertyInfo = item.PropertyInfo;
var propertyType = propertyInfo.PropertyType;
var isAscending = item.Direction == ListSortDirection.Ascending;
if (thenBy)
{
var prevExpr = Expression.Parameter(typeof (IOrderedEnumerable<T>), "prevExpr");
var expr1 = Expression.Lambda<Func<IOrderedEnumerable<T>, IOrderedEnumerable<T>>>(
Expression.Call(
(isAscending ? thenByMethod : thenByDescendingMethod).MakeGenericMethod(typeOfT, propertyType),
prevExpr,
Expression.Lambda(
typeof (Func<,>).MakeGenericType(typeOfT, propertyType),
Expression.MakeMemberAccess(oExpr, propertyInfo),
oExpr)
),
prevExpr)
.Compile();
result = expr1(result);
}
else
{
var prevExpr = Expression.Parameter(typeof (IEnumerable<T>), "prevExpr");
var expr1 = Expression.Lambda<Func<IEnumerable<T>, IOrderedEnumerable<T>>>(
Expression.Call(
(isAscending ? orderByMethod : orderByDescendingMethod).MakeGenericMethod(typeOfT, propertyType),
prevExpr,
Expression.Lambda(
typeof (Func<,>).MakeGenericType(typeOfT, propertyType),
Expression.MakeMemberAccess(oExpr, propertyInfo),
oExpr)
),
prevExpr)
.Compile();
result = expr1(source);
thenBy = true;
}
}
return result;
}
private static MethodInfo orderByMethod =
MethodOf(() => Enumerable.OrderBy(default(IEnumerable<object>), default(Func<object, object>)))
.GetGenericMethodDefinition();
private static MethodInfo orderByDescendingMethod =
MethodOf(() => Enumerable.OrderByDescending(default(IEnumerable<object>), default(Func<object, object>)))
.GetGenericMethodDefinition();
private static MethodInfo thenByMethod =
MethodOf(() => Enumerable.ThenBy(default(IOrderedEnumerable<object>), default(Func<object, object>)))
.GetGenericMethodDefinition();
private static MethodInfo thenByDescendingMethod =
MethodOf(() => Enumerable.ThenByDescending(default(IOrderedEnumerable<object>), default(Func<object, object>)))
.GetGenericMethodDefinition();
public static MethodInfo MethodOf<T>(Expression<Func<T>> method)
{
MethodCallExpression mce = (MethodCallExpression) method.Body;
MethodInfo mi = mce.Method;
return mi;
}
}
public static class Sample
{
private static void Main()
{
var data = new List<Customer>
{
new Customer {ID = 3, Name = "a"},
new Customer {ID = 3, Name = "c"},
new Customer {ID = 4},
new Customer {ID = 3, Name = "b"},
new Customer {ID = 2}
};
var result = data.BuildOrderBys(
new SortDescription("ID", ListSortDirection.Ascending),
new SortDescription("Name", ListSortDirection.Ascending)
).Dump();
}
}
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
}
LinqPad中显示的样本结果
内容总结
以上是互联网集市为您收集整理的c# – 列表顺序的动态链接全部内容,希望文章能够帮你解决c# – 列表顺序的动态链接所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。