【问题标题】:What is the best and optimal way to return multiple anonymous type lists in C#?在 C# 中返回多个匿名类型列表的最佳和最佳方法是什么?
【发布时间】:2017-11-06 09:22:34
【问题描述】:

我有 3 个 System.Collections.Generic.List<<anonymous type: System.DateTime.Week, int Count>>. 类型的列表

在我的程序中,我使用类型列表(比如说 detailsList),其中包含从数据库中获取的数据。

使用这个 detailsList 我正在创建 3 个单独的列表,它们的类型为 System.Collections.Generic.List<<anonymous type: System.DateTime.Week, int Count>>.

这些列表的 Select 部分基本上如下:

detailsList
    .Where(where_part)
    .Select(x => x.Week)
    .GroupBy(x => x.Week)
    .(x => new { Week = x.Key, Count = x.Count() })
    .ToList();

如何使用最佳方式从方法中返回这些列表? 在这种情况下,此方法的返回类型是什么?

注意:被退回后,我想再次单独访问这些列表,因为我需要使用这些列表填写 3 个不同的数据表。

【问题讨论】:

  • 最好的答案就是 not 使用匿名类型。在 C# 7 中——至少在应用程序中——我会使用元组类型。这对你来说是一个选择吗?
  • 可以使用对象类型
  • 如何建立这些列表?列表返回后您打算如何使用它们?
  • 匿名类型只是为了方便。编译器为您创建类型,因此您避免自己显式地执行此操作。但是,这些类型不能用作函数返回类型(或函数参数)。如果要从函数返回特定类型,则不能使用匿名类型。 C# 7 值元组为您提供了匿名类型的一些便利,因为您不必在其他地方指定类型。它在签名中指定。

标签: c# asp.net list generic-list


【解决方案1】:

注意:此答案的第一部分适用于 C#6。如果使用 C#7,您可以使用 C#7 的内置元组返回类型,如最后所述。


您的代码:

detailsList.Where(where_part).Select(x=>x.Week).GroupBy(x=>x.Week).Select(x=>x.Count)

...不选择匿名类型。这将返回一个IEnumerable<int>。如果您想要周/计数对列表,您需要这样做:

detailsList.Where(where_part).Select(x=>x.Week).GroupBy(x=>x.Week)
   .Select(x=>new {Week = x.Key, x.Count()})

不管怎样,如果我理解了这个问题,你想返回三个列表,比如(编个例子):

  1. 每周烘焙的蛋糕数量
  2. 每周售出的蛋糕数量
  3. 每周燃烧的蛋糕数

...列表中的每个元素看起来都类似于{Week: 3, Count: 22}

您可以使用Tuple 来存储星期/计数对。没有typeSystem.DateTime.Week,它只是一个int,所以合适的TupleTuple<int, int>。所以你会返回几个Lists(或IListICollection甚至IEnumerables)。

[令我震惊的是,您可能会使用这些列表来查找给定“周”的“计数”——在这种情况下,创建 Dictionary<int, int> 而不是 @987654335 可能更方便@Tuple<int, int>s。在这种情况下,您可以将最后一个 Select 替换为 ToDictionary() 调用。]

无论如何,您现在遇到的问题是如何从您的方法中返回三个这些列表(或字典)。您有多种选择:

  1. 不要。创建三个方法:-)
  2. 返回一个聚合列表的对象(一个数组、另一个列表、另一个元组,甚至是您自己的类型)。
  3. 使用 3 个“输出”参数。

无论您选择哪种方式,使用Tuple 类型将允许您相对轻松地声明返回值/输出参数的类型。就个人而言,我可能会创建自己的返回类型,例如:

class CakeInfo
{
    List<Tuple<int, int>> CakesBakedByWeek { get; private set; }
    List<Tuple<int, int>> CakesSoldByWeek { get; private set; }
    List<Tuple<int, int>> CakesBurntByWeek { get; private set; }

    public CakeInfo(
        IEnumerable<Tuple<int, int>> baked, 
        IEnumerable<Tuple<int, int>> sold, 
        IEnumerable<Tuple<int, int>> burnt
    )
    {
        CakesBakedByWeek = baked.ToList();
        CakesSolByWeek = sold.ToList();
        CakesBurntByWeek = burnt.ToList();
    } 
}

...除了我永远不会只使用List :-) ...在这种情况下,我会使用IReadOnlyCollection&lt;Tuple&lt;int, int&gt;&gt;IReadOnlyDictionary&lt;int, int&gt;

要使用它,您的 GetCakeInfo 方法可能类似于:

public CakeInfo GetCakeInfo()
{
    var detailsList = ...;

    var baked = detailsList.Where(where_part_baked).Select(x=>x.Week).GroupBy(x=>x.Week)
       .Select(x=>new Tuple<int, int>(x.Key, x.Count()));

    var sold = detailsList.Where(where_part_sold).Select(x=>x.Week).GroupBy(x=>x.Week)
       .Select(x=>new Tuple<int, int>(x.Key, x.Count()));

    var burnt = detailsList.Where(where_part_burnt).Select(x=>x.Week).GroupBy(x=>x.Week)
       .Select(x=>new Tuple<int, int>(x.Key, x.Count()));

    return new CakeInfo(baked, sold, burnt);
}

(当然,你可以有一个辅助方法来分解上面的重复代码)。


C#7

如果您使用的是 C#7,那么您可以更轻松地通过使用元组返回类型将所有三个列表作为方法的返回值返回:

public (
    List<Tuple<int, int>> baked,
    List<Tuple<int, int>> sold,
    List<Tuple<int, int>> burnt
) GetCakeInfo()
{
    ...
    return (baked, sold, burnt);
}

你会这样称呼它:

(List<Tuple<int, int>> baked, List<Tuple<int, int>> sold, List<Tuple<int, int>> burnt) = GetCakeInfo();

...或...

var cakeLists = GetCakeInfo();
var baked = cakeLists.baked;
// ...

此外,列表元素可以使用新的ValueTuple 类型而不是旧的Tuple 类型。所以:

public (
    List<(int week, int count)> baked,
    List<(int week, int count)> sold,
    List<(int week, int count)> burnt
) GetCakeInfo()
{
    ...
    return (baked, sold, burnt);
}

【讨论】:

    【解决方案2】:

    您可以创建一个与您的输出匹配的视图模型并使用它来创建 System.Collections.Generic.List&lt;YourViewModel&gt; 。然后你就可以退货了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-18
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      相关资源
      最近更新 更多