List<T> 动态拼接

List<T> Concatenation dynamically

我正在尝试按如下方式连接 List<>-

 List<Student> finalList = new List<Student>();
 var sortedDict = dictOfList.OrderBy(k => k.Key);
 foreach (KeyValuePair<int, List<Student>> entry in sortedDict) {          
     List<Student> ListFromDict = (List<Student>)entry.Value;
     finalList.Concat(ListFromDict);
 }

但没有发生串联。入围者仍然是空的。有帮助吗?

您可能需要阅读有关 Enumerable.Concat 的文档:

Return Value
Type: System.Collections.Generic.IEnumerable
An IEnumerable that contains the concatenated elements of the two input sequences.

所以您可能想要使用 return 值,它包含新元素。

作为替代,您可以使用 List.AddRange,它 将指定集合的​​元素添加到列表的末尾

顺便说一句,您还可以通过一个简单的 LINQ 查询来实现您的目标:

var finalList = dictOfList.OrderBy(k => k.Key)
                          .SelectMany(k => k.Value)
                          .ToList();

按照指定 hereConcat 生成一个新序列,而 AddRange 实际上将元素添加到列表中。因此,您应该将其重写为:

List<Student> finalList = new List<Student>();
var sortedDict = dictOfList.OrderBy(k => k.Key);
foreach (KeyValuePair<int, List<Student>> entry in sortedDict) {          
    List<Student> ListFromDict = (List<Student>)entry.Value;
    finalList.AddRange(ListFromDict);
}

此外,您可以通过省略对 List<T> 对象的强制转换来稍微提高效率,因为 entry.Value 已经是一个 List<T>(技术上只需要是一个 IEnumerable<T>):

var sortedDict = dictOfList.OrderBy(k => k.Key);
foreach (KeyValuePair<int, List<Student>> entry in sortedDict) {
    finalList.AddRange(entry.Value);
}

调用 Concat 不会修改原始列表,而是 returns 一个新列表 - 或者完全准确地说:它 returns 一个 IEnumerable<string>将产生连接的两个列表的内容,而不修改它们中的任何一个。

您可能想使用 AddRange 来满足您的需求:

List<Student> ListFromDict = (List<Student>)entry.Value;
finalList.AddRange(ListFromDict);

甚至更短(一行代码):

finalList.AddRange((List<Student>)entry.Value);


因为 entry.Value 已经是 List<Student> 类型,你可以只使用这个:

finalList.AddRange(entry.Value);

Concat 方法不修改原始集合,而是 returns 具有串联结果的全新集合。因此,请尝试 finalList = finalList.Concat(ListFromDict) 或使用 AddRange 修改目标列表的方法。

其他答案已经解释了为什么 Concat 对您没有帮助 - 但它们都保留了您的原始循环。没有必要 - LINQ 已涵盖:

List<Student> finalList = dictOfList.OrderBy(k => k.Key)
                                    .SelectMany(pair => pair.Value)
                                    .ToList();

需要说明的是,这会替换整个现有代码,而不仅仅是循环体。

更简单 :) 每当您发现自己使用的 foreach 循环只构建另一个集合时,就值得一看是否可以使用 LINQ 消除该循环。