Can I use StringBuilder elements in a foreach?

39,325

Solution 1

A StringBuilder doesn't store the lines that you append. It simply is used to build the final string. Assuming you've added everything to the StringBuilder already, you can do:

// Write the complete string to the serialPort
serialPort.Write(linesToSend.ToString());

Solution 2

Old question, I know, but something potentially useful:

If each of your strings were built with .AppendLine or you inserted a new line, you can do

string[] delim = { Environment.NewLine, "\n" }; // "\n" added in case you manually appended a newline
string[] lines = StringBuilder.ToString().Split(delim, StringSplitOptions.None);
foreach(string line in lines){
    // Do something
}

Solution 3

This is correct. A StringBuilder is designed to help you build one final output string as the others have stated.

If you have a variable number of strings you need to work on, you can use an ArrayList and iterate over that.

ArrayList strings = new ArrayList();
// populate the list
foreach (string str in strings) {
  // do what you need to.
}

If you're afraid that the array list might contain other objects (as it isn't strongly typed) you can cast it safely instead:

foreach (object obj in strings) {
  string str = obj as string;
  // If null strings aren't allowed, you can use the following
  // to skip to the next element.
  if (str == null) {
    continue;
  }
}

Solution 4

A StringBuilder is building just one string, so how could you foreach it to get a whole sequence of strings?

If you need to write line by line, maybe use an ArrayList, add each line string to that, and foreach with string as the foreach variable type (Object will be cast to String). Or even better, use StringCollection (thank to comment by Anthony Pegram, to the original question; I had forgotten this class).

But why not upgrade to a newer version of .NET?

Solution 5

The foreach loop works by calling the GetEnumerator from the interface IEnumerable which will return an enumerator that foreach uses to get the next element of the object.

StringBuilder does not implement IEnumerable or IEnumerable<T> which would allow the foreach to work. You are better off using a string[] or StringCollection in this case and when you are done you can concatenate the collection using a StringBuilder.

ex:

StringBuilder stringBuilder = new StringBuilder();
foreach(string line in array)
{
    serialPort.Write(line);
    stringBuilder.Append(line);
}
Share:
39,325
B. Clay Shannon-B. Crow Raven
Author by

B. Clay Shannon-B. Crow Raven

My novel about climate change and social justice featuring talking animals traveling through time and space to prevent disasters is now available on amazon, in three formats: Taterskin &amp; The Eco Defenders Kindle eBook; Taterskin &amp; The Eco Defenders Paperback; Taterskin &amp; The Eco Defenders Hardcover Taterskin &amp; The Eco Defenders, told in “first canine” by the titular character, a Labrador Retriever, is the story of a few humans and several talking animals who travel through time and space to make the past—and thus the future—a better place. The improvements effected by the Eco Defenders benefit not just the earth itself, but also mistreated humans and animals. In Book 1 (“Wonders Never Cease”), The Eco Defenders travel 150 million years into the past, to meet a Pterodactyl and make plans to “nip Nazism in the bud.” After that, it's on to 1787 Australia to protect the indigenous people and the environment there. The Eco Defenders next go to India, where they assemble animals from all over that country to put an end to Thuggee and fights to the death between Cobras and Mongooses. Their final stop is 1885 Africa, where the Eco Defenders band together with the local animals to prevent King Leopold of Belgium from taking control of the Congo, following which they put an end to the poaching of animals throughout the continent. Book 2 (“Tell it to Future Generations”) takes up with the Eco Defenders following up on their earlier adventures by 1) Preventing the American Civil War in 1861, after which a slave they free joins them; 2) Saving the Indians from being massacred at Wounded Knee in 1890, following which Chapawee, a Sioux Indian, joins the Eco Defenders; 3) Putting an end to the practice of vivisection (experimentation on live animals) in 1903; 4) Coming to the aid of exploited workers in 1911 Manhattan, saving hundreds from the Triangle Shirtwaist Fire; and 5) Traveling to the Amazon Basin in 1978 to protect and preserve the Amazon rainforest. @@@@@@@@@@@@@@@@@@@@@@@ I have lived in eight states; besides my native California (where I was born and where I now again reside), in chronological order I have infested: New York (Brooklyn), Montana (Helena), Alaska (Anchorage), Oklahoma (Bethany), Wisconsin (New Berlin and Oconomowoc), Idaho (Coeur d'Alene), and Missouri (Piedmont). I am a writer of both fiction (for which I use the nom de guerre "Blackbird Crow Raven", as a nod to my Native American heritage - I am "½ Cowboy, ½ Indian") and nonfiction, including a two-volume social and cultural history of the U.S. which covers important events from 1620-2006 and can be downloaded gratis here.

Updated on July 30, 2020

Comments

  • B. Clay Shannon-B. Crow Raven
    B. Clay Shannon-B. Crow Raven over 3 years

    Since I'm using .NET 1.1, I can't use a generic List of string, as generics were not part of the language yet. So I'm trying to use a StringBuilder, but get this err msg:

    "foreach statement cannot operate on variables of type 'System.Text.StringBuilder' because 'System.Text.StringBuilder' does not contain a definition for 'GetEnumerator', or it is inaccessible"

    with this code:

    public StringBuilder linesToSend;
    . . .
    
    foreach (string _line in this.linesToSend)
    {
        serialPort.Write(_line);
    }
    

    Is there something wrong with my code, or is StringBuilder really disallowed from foreach loops? If the latter, is String[] my best recourse?

  • B. Clay Shannon-B. Crow Raven
    B. Clay Shannon-B. Crow Raven about 11 years
    For this project, I can't upgrade. In other project, I AM using Visual Studio 2010 on Windows 7 and VS 2012 on Windows 8, but this project will remain in VS 2003 / .NET 1.1
  • Captain Kenpachi
    Captain Kenpachi about 11 years
    It is mutable, i.e. you don't have to indicate the number of items you're going to put into it beforehand. Although, I meant Collection rather than Dictionary. sorry.
  • supercat
    supercat about 11 years
    The foreach loop actually duck-types its operand. If the operand has a method called GetEnumerator whose return type includes a parameterless method called MoveNext that returns bool, and a readable property named Current that returns the control-variable type, then foreach will use without regard for whether the type implements IEnumerable or IEnumerable<T> [if the type explicitly implements IEnumerable<T>, but defines a GetEnumerator method separate from the interface, a foreach loop will use the latter].