【问题标题】:ASP.NET Core using Func as a parameter in a method to do orderby and thenbyASP.NET Core 使用 Func 作为参数在方法中执行 orderby 和 thenby
【发布时间】:2019-08-25 07:28:53
【问题描述】:

我对此感到困惑。一位朋友前段时间写了这篇文章,现在在另一个州,所以无法帮助扩展这个想法。

// 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&lt;T&gt;&lt;string, SortDirection&gt; 字典,其中 SortDirection 是枚举的方向:

public enum SortDirection
{
    asc = 0,
    desc
}

这是因为字典可能有多达 4 列可供排序。第一个值始终是orderBy,其他所有值都是thenBy

所以我尝试从以下方法签名开始。

public static IOrderedEnumerable<T> OrderAndThenBy(IEnumerable<T> list, Func<T, Dictionary<string, SortDirection>>){}

我想接受一个 IEnumerable,然后使用带有列的字典按“字符串”和它的排序方向进行排序。

This answer by Matthias 似乎很有希望,但核心是我不了解 Func 如何作为参数工作的机制,以便在IEnumerable&lt;T&gt; 上使用&lt;key = columns, value = sortDirection&gt; 的字典(通用,所以我可以使用它在我需要排序的所有表上)然后返回IOrderedEnumerable&lt;T&gt;..

有人可以帮助了解方法的结构,以及如何使用 Func 作为方法参数,其中一个参数为 Dictionary 类型。目前我在“T”上遇到错误..

错误 CS0246 找不到类型或命名空间名称“T”(您是否缺少 using 指令或程序集引用?)

因为我没有正确编写泛型方法参数。希望有人能提供帮助。

【问题讨论】:

  • 我不确定我是否理解正确,但取决于您的表格关系。您可以使用 2 个 orderby。像这样..clients.OrderBy(keySelector1).OrderBy(keySelector2)
  • 为什么要使用static 方法?这不符合您的要求。
  • 鉴于您可以在返回之前多次执行var query2 = query1.SomeOrderMethod();,因此您可以自己写出来。
  • 嗨 Henk,我收到一条查询语句,我分解了过滤器和排序。我想要通用的那种,因为我想要它不仅适用于客户表,而且适用于工作表等等。是的,我可以在每一个中一次又一次地写这个,但更好的是不是拥有可重用的代码,即运行在所有需要排序的服务之间共享的通用方法。我也想使用 Func 语句,我觉得它应该是一个静态方法,所以我不必实例化它......我也觉得有很多人对 Func 也有问题并想要一个例子。跨度>
  • 所以.. 通用,因为被排序的表可以更改,当然每个表都有不同的列进行排序,它们也可以是 asc 或 desc,最重要的是它的 orderby 和 thenby..它可能是一列或 4 列 - 在你拿到字典之前你不知道.. 所以它特别灵活。

标签: c# asp.net linq asp.net-core


【解决方案1】:

您收到错误是因为您需要在名称后面的方法声明中包含泛型类型 T(参见 [1]),如下所示:

public static IOrderedEnumerable<T> OrderAndThenBy<T>(IEnumerable<T> list, Func<T, Dictionary<string, SortDirection>> sortInfo){}

OrderBy 方法提供按(键)排序的属性信息要像您正在尝试的字符串一样困难得多,因此您最好像在初始OrderClients 方法中一样保留键选择。在那里,keySelector 是一个委托 [3, 2],它接受 Client,并返回 Client 的属性,以便 OrderBy 方法知道您要按哪个属性排序。 既然您有多个属性,它们都可能具有不同的类型,那么仅提供一个类型参数是不够的。但由于您也不知道要排序的属性数量,因此您无法静态定义所有类型参数。 由于不是最干净但简单的解决方法,您可以删除类型,并将委托更改为返回 object 而不是 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2014-03-04
    • 1970-01-01
    • 2018-09-16
    相关资源
    最近更新 更多