注意:此答案的第一部分适用于 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()})
不管怎样,如果我理解了这个问题,你想返回三个列表,比如(编个例子):
- 每周烘焙的蛋糕数量
- 每周售出的蛋糕数量
- 每周燃烧的蛋糕数
...列表中的每个元素看起来都类似于{Week: 3, Count: 22}。
您可以使用Tuple 来存储星期/计数对。没有typeSystem.DateTime.Week,它只是一个int,所以合适的Tuple 是Tuple<int, int>。所以你会返回几个Lists(或IList、ICollection甚至IEnumerables)。
[令我震惊的是,您可能会使用这些列表来查找给定“周”的“计数”——在这种情况下,创建 Dictionary<int, int> 而不是 @987654335 可能更方便@Tuple<int, int>s。在这种情况下,您可以将最后一个 Select 替换为 ToDictionary() 调用。]
无论如何,您现在遇到的问题是如何从您的方法中返回三个这些列表(或字典)。您有多种选择:
- 不要。创建三个方法:-)
- 返回一个聚合列表的对象(一个数组、另一个列表、另一个元组,甚至是您自己的类型)。
- 使用 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<Tuple<int, int>> 或IReadOnlyDictionary<int, int>。
要使用它,您的 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);
}