gpt4 book ai didi

linq - 使用 LINQ 动态排序

转载 作者:行者123 更新时间:2023-12-04 09:56:10 25 4
gpt4 key购买 nike

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

我有一个字符串,它反射(reflect)了集合应该作为排序依据的属性的名称。另外,我有一个排序方向。我如何动态地将此排序信息应用到我的收藏中?请注意排序可以是多层的,例如我可以按姓氏排序,然后按名字排序。

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

var results = myCollection.OrderBy(sortProperty);

但是,我收到一条消息,内容为:

... 不包含 'OrderBy' 的定义,并且最好的扩展方法重载 ... 有一些无效的参数。

最佳答案

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

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

// 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条款正常:)

关于linq - 使用 LINQ 动态排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4726047/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com