使用LINQ动态排序 [英] Dynamically Sorting with LINQ

查看:55
本文介绍了使用LINQ动态排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组CLR对象.该对象的类定义具有三个属性:FirstName,LastName,BirthDate.

I have a collection of CLR objects. The class definition for the object has three properties: FirstName, LastName, BirthDate.

我有一个字符串,该字符串反映了应该对集合进行排序的属性的名称.另外,我有一个排序方向.如何动态地将此排序信息应用于我的收藏集?请注意,排序可以是多层的,例如,我可以按姓氏排序,然后按名字排序.

I have a string that reflects the name of the property the collection should be sorted by. In addition, I have a sorting direction. How do I dynamically apply this sorting information to my collection? Please note that sorting could be multi-layer, so for instance I could sort by LastName, and then by FirstName.

目前,我正在尝试以下方法,但没有任何运气:

Currently, I'm trying the following without any luck:

var results = myCollection.OrderBy(sortProperty);

但是,我收到一条消息,提示:

However, I'm getting a message that says:

...不包含对'OrderBy'的定义,最佳扩展方法重载...具有一些无效的参数.

推荐答案

好的,我在评论中与SLaks的争论迫使我想出一个答案:)

Okay, my argument with SLaks in his comments has compelled me to come up with an answer :)

我假设您只需要支持LINQ to Objects.这是一些需要添加大量验证但有效的代码:

I'm assuming that you only need to support LINQ to Objects. Here's some code which needs significant amounts of validation adding, but does work:

// We want the overload which doesn't take an EqualityComparer.
private static MethodInfo OrderByMethod = typeof(Enumerable)
    .GetMethods(BindingFlags.Public | BindingFlags.Static)
    .Where(method => method.Name == "OrderBy" 
           && method.GetParameters().Length == 2)
    .Single();

public static IOrderedEnumerable<TSource> OrderByProperty<TSource>(
    this IEnumerable<TSource> source,
    string propertyName) 
{
    // TODO: Lots of validation :)
    PropertyInfo property = typeof(TSource).GetProperty(propertyName);
    MethodInfo getter = property.GetGetMethod();
    Type propType = property.PropertyType;
    Type funcType = typeof(Func<,>).MakeGenericType(typeof(TSource), propType);
    Delegate func = Delegate.CreateDelegate(funcType, getter);
    MethodInfo constructedMethod = OrderByMethod.MakeGenericMethod(
        typeof(TSource), propType);
    return (IOrderedEnumerable<TSource>) constructedMethod.Invoke(null,
        new object[] { source, func });
}

测试代码:

string[] foo = new string[] { "Jon", "Holly", "Tom", "William", "Robin" };

foreach (string x in foo.OrderByProperty("Length"))
{
    Console.WriteLine(x);
}

输出:

Jon
Tom
Holly
Robin
William

它甚至返回一个IOrderedEnumerable<TSource>,因此您可以像平常一样将ThenBy子句链接起来:)

It even returns an IOrderedEnumerable<TSource> so you can chain ThenBy clauses on as normal :)

这篇关于使用LINQ动态排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆