Using StringBuilder.Append() in a lambda expression is producing an empty string

I'm trying to append a list of strings(> 10),so to avoid creating a lot of strings I am using a StringBuilder.It would be great if someone explains why this is happening..

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;

public class Program
    public static void Main()
        var lst = new List<string>(){"A", "B", "C"};
        StringBuilder sb = new StringBuilder();
        lst.Select(str => sb.Append(str.ToLower()));
        Console.Write("Output: {0}", sb.ToString());

Run the code here-dotnetfiddle

Jon Skeet

As has been noted in other answers, the laziness of Select is the problem here. I'd add that more broadly, using side-effects (such as appending to a StringBuilder) is generally a bad idea within a LINQ query. Each selector, condition etc should ideally be side-effect-free.

As Gilad pointed out, you can use string.Concat in this case - but you'll need to use Select to convert each value to lower case, unless you want to do that after the fact (which may have a different result in some corner cases, I suspect).

So either:

var list = new List<string> { "A", "B", "C" };
string result = string.Concat(list.Select(str => str.ToLower()));

Or, with a possibly different result, but creating fewer strings:

var list = new List<string> { "A", "B", "C" };
string result = string.Concat(list).ToLower();

Given the existence of string.Concat, I wouldn't start using a foreach loop or List.ForEach etc... there's no need to do this "manually" when it's built into the framework.

You might also want to consider using ToLowerInvariant instead of ToLower, depending on exactly what you're trying to do. Casing is surprisingly complicated.


See more on this question at Stackoverflow