Can I use StringBuilder elements in a foreach?
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);
}
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 & The Eco Defenders Kindle eBook; Taterskin & The Eco Defenders Paperback; Taterskin & The Eco Defenders Hardcover Taterskin & 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, 2020Comments
-
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 about 11 yearsFor 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 about 11 yearsIt 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 about 11 yearsThe
foreach
loop actually duck-types its operand. If the operand has a method calledGetEnumerator
whose return type includes a parameterless method calledMoveNext
that returnsbool
, and a readable property namedCurrent
that returns the control-variable type, thenforeach
will use without regard for whether the type implementsIEnumerable
orIEnumerable<T>
[if the type explicitly implementsIEnumerable<T>
, but defines aGetEnumerator
method separate from the interface, aforeach
loop will use the latter].