为什么我无法在 LINQ Select() 查询中向 StringBuilder 插入值

Why am I not able to insert a value to a StringBuilder inside a LINQ Select() query

为什么我无法通过 LINQ Select() 查询将列表中的字符串值插入到 StringBuilder 中?

鉴于下面的代码,我希望最后构建的字符串是 {CBA},但实际上是 {}

我错过了什么?

var testList = new List<string>
{
   "A",
   "B",
   "C"
};

var testStringBuilder = new StringBuilder("{}");
testList.Select(y => testStringBuilder.Insert(1,y));

Selectreturns列表StringBuilder

你必须做一个循环才能做到这一点。使用 for 循环

foreach(var y in testList)
{
    testStringBuilder.Insert(1,y);
}

ForEach 的 linq。

testList.ForEach(y => testStringBuilder.Insert(1,y));

Linq 是惰性的 - 大多数 linq 方法在您实际迭代查询之前不会执行。

无论如何,

Select 不是正确的使用方式。它是一个映射函数——对于集合中的每个元素,它以某种方式对其进行转换,并 returns 转换后的元素。编写具有副作用的 Select(或任何 linq 方法)通常是一个非常糟糕的主意。

你正在做的是获取每个元素并用它做一些事情 - 这是 foreach 循环的用例:

foreach (var element in testList)
{
    testStringBuilder.Insert(1, element);
}

不要试图为此使用 List<T>.ForEach。它仅适用于 List<T>,不适用于任何其他集合:它被故意排除在 Linq 之外,因为它的存在被认为是一个错误。参见 Eric Lippert's reasoning

正如@canton7 所说,Linq 是懒惰的。

您可以强制执行您使用 ToList() 方法创建的 select 查询

testList.Select(y => testStringBuilder.Insert(1, y)).ToList()

但是,为了提高效率,强烈推荐 foreach 循环

编辑

有人能解释一下为什么我得到 -1 吗? 这个方法很管用,我从来没有说过那是最好的,但我认为它有助于更​​好地理解 linq 的工作原理