c# - ASP.NET Core 使用 Func 作为参数在方法中执行 orderby 和 thenby
问题描述
我在纠结这个。一位朋友前段时间写了这篇文章,现在在另一个州,所以无法帮助扩展这个想法。
// For index listing.
// Order function to identify sort direction.
private IOrderedEnumerable<Client> OrderClients<T>(IEnumerable<Client> clients, Func<Client, T> keySelector, SortDirection sortDirection) {
return sortDirection == SortDirection.desc
? clients.OrderByDescending(keySelector)
: clients.OrderBy(keySelector);
}
有用。
不过我的要求变了。
我现在想要一个静态方法,它可以提供一个IEnumerable<T>
和一个字典,<string, SortDirection>
其中SortDirection
的方向是枚举:
public enum SortDirection
{
asc = 0,
desc
}
这是因为 Dictionary 可能有多达 4 列可供排序。第一个值始终是orderBy
,其他所有值都是thenBy
。
所以我尝试从以下方法签名开始。
public static IOrderedEnumerable<T> OrderAndThenBy(IEnumerable<T> list, Func<T, Dictionary<string, SortDirection>>){}
我想接受一个 IEnumerable,然后使用带有列的字典按“字符串”和它应该排序的方向进行排序。
Matthias 的这个答案似乎很有希望,但在这个问题的核心,我不明白 Func 如何作为参数工作的机制,以便使用(generic 所以我可以在我需要排序的所有表上使用它<key = columns, value = sortDirection>
的字典) IEnumerable<T>
) 然后返回一个IOrderedEnumerable<T>
..
有人可以帮助解决方法的结构以及如何将 Func 用作方法参数和一个 Dictionary 类型的参数。目前我在“T”上遇到错误..
错误 CS0246 找不到类型或命名空间名称“T”(您是否缺少 using 指令或程序集引用?)
因为我没有正确编写泛型方法参数。希望有人能提供帮助。
解决方案
您会收到错误消息,因为您需要T
在名称之后的方法声明中包含泛型类型(请参阅 [1]),如下所示:
public static IOrderedEnumerable<T> OrderAndThenBy<T>(IEnumerable<T> list, Func<T, Dictionary<string, SortDirection>> sortInfo){}
像您尝试的那样将要按(键)排序的属性作为字符串提供给方法要困难得多OrderBy
,因此您最好像在初始OrderClients
方法中一样保留键选择。那里keySelector
是一个委托 [3, 2] ,它接受 aClient
并返回 的一个属性Client
,以便OrderBy
方法知道您要按哪个属性排序。既然您有多个属性,它们都可能具有不同的类型,那么仅提供一个类型参数是不够的。但是由于您也不知道要排序的属性数量,因此您无法静态定义所有类型参数。object
由于不是最干净但简单的解决方法,您可以删除类型,并将委托更改为 return T
。
您可能仍然只使用Clients
,因此您应该保留原始方法的返回类型。
请注意,字典中元素的顺序是未定义的 [4],但在这种情况下顺序很重要,因此您应该将其替换为例如列表 [5]。
综上所述,您可能会想出如下方法:
public static IOrderedEnumerable<Client> OrderAndThenBy(IEnumerable<Client> list, List<KeyValuePair<Func<Broker, object>, SortDirection>> sortInfo) {}
[1] https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-methods
[2] https://docs.microsoft.com/en-us/dotnet/api/system.func-2?view=netframework-4.8
[3] https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/
[4] https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2
[5] https://docs.microsoft.com/en-us/dotnet/standard/collections/selecting-a-collection-class