English 中文(简体)
LINQ to append to a StringBuilder from a String[]
原标题:

I ve got a String array that I m wanting to add to a string builder by way of LINQ.

What I m basically trying to say is "For each item in this array, append a line to this StringBuilder".

I can do this quite easily using a foreach loop however the following code doesn t seem to do anything. What am I missing?

stringArray.Select(x => stringBuilder.AppendLine(x));

Where as this works:

foreach(String item in stringArray)
{
  stringBuilder.AppendLine(item);
}
最佳回答

If you insist on doing it in a LINQy way:

StringBuilder builder = StringArray.Aggregate(
                            new StringBuilder(),
                            (sb, s) => sb.AppendLine(s)
                        );

Alternatively, as Luke pointed out in a comment on another post, you could say

Array.ForEach(StringArray, s => stringBuilder.AppendLine(s));

The reason that Select does not work is because Select is for projecting and creating an IEnumerable of the projection. So the line of code

StringArray.Select(s => stringBuilder.AppendLine(s))

does not iterate over the StringArray calling stringBuilder.AppendLine(s) on each iteration. Rather, it creates an IEnumerable<StringBuilder> that can be enumerated over.

I suppose that you could say

var e = stringArray.Select(x => stringBuilder.AppendLine(x));
StringBuilder sb = e.Last();
Console.WriteLine(sb.ToString());

but that is really hideous.

问题回答

Use the "ForEach" extension method instead of "Select".

stringArray.ToList().ForEach(x => stringBuilder.AppendLine(x));

or

Array.ForEach(stringArray, x => stringBuilder.AppendLine(x));

If you re using .NET core then this will work:

stringBuilder.AppendJoin(Environment.NewLine, stringArray);

Although it s not leveraging LINQ, but it does get it done in one line without adding any extra code.

stringArray.DoForAll(x => StringBuilder.AppendLine(x));

Where, DoForAll is an extension method:

public static class CommonExtensions 
{ 
    public static void DoForAll<T>(this IEnumerable<T> items, Action<T> action) where T: class 
    { 
        if (action == null) 
            throw new ArgumentNullException("action"); 
        foreach (var item in items) 
            action(item);   
    }
} 




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签