C# String Handling – string vs StringBuilder vs StringBuffer
1. What is the difference between string, StringBuilder, and StringBuffer?
In C#, string and StringBuilder are used to store and manipulate text. However, they differ in how they handle modifications, memory allocation, and performance.
Important: C# supports string and StringBuilder, but does not have a built-in StringBuffer class. StringBuffer is available in Java.
1. What is string in C#?
A string is an immutable reference type used to store a sequence of characters.
Immutable means that once a string object is created, its contents cannot be changed.
When you modify a string, a new string object is created rather than changing the existing object.
Example:
string name = "Hello";
name = name + " World";
Console.WriteLine(name);
Output:
Hello World
How does it work internally?
Step 1:
name -----> "Hello"
Step 2:
name = name + " World"
New String Object
|
v
name -----> "Hello World"
Old Object:
"Hello"
|
v
Eligible for Garbage Collection
(if no references remain)
Explanation:
-
Initially,
"Hello"is assigned toname. -
When
" World"is appended, a new string containing"Hello World"is created. -
The variable
namenow references the new string. -
The old string object remains unchanged and may be collected if no longer referenced.
Key Points:
-
stringis immutable. -
It is a reference type.
-
Repeated modifications can create additional objects.
-
It is convenient for fixed or infrequently modified text.
-
It is commonly used for names, email addresses, messages, and API responses.
-
String literals may be interned by the .NET runtime.
2. What is StringBuilder in C#?
StringBuilder is a mutable class available in the System.Text namespace.
Mutable means its contents can be modified without creating a new string object for every operation.
It is particularly useful when performing repeated string modifications.
Example:
using System.Text;
StringBuilder sb = new StringBuilder("Hello");
sb.Append(" World");
sb.Append(" C#");
Console.WriteLine(sb.ToString());
Output:
Hello World C#
How does it work internally?
Step 1:
StringBuilder Object
|
v
"Hello"
Step 2:
sb.Append(" World")
|
v
"Hello World"
Step 3:
sb.Append(" C#")
|
v
"Hello World C#"
Result:
The same StringBuilder object is used.
Note:
Its internal buffer may grow or
allocate additional storage.
Explanation:
-
A
StringBuilderobject is created with"Hello". -
Append()adds text to its mutable contents. -
Subsequent
Append()operations reuse the same builder object. -
ToString()produces a regular immutable string.
Unlike string, StringBuilder does not require a new string object for each append operation.
Common StringBuilder Methods
|
Method |
Purpose |
|---|---|
|
|
Adds text at the end |
|
|
Adds text followed by a newline |
|
|
Inserts text at a specified position |
|
|
Removes characters |
|
|
Replaces text |
|
|
Removes all content |
|
|
Converts the contents to a string |
Example:
StringBuilder sb = new StringBuilder("Hello");
sb.Append(" World");
sb.Replace("World", "C#");
sb.Insert(0, "Welcome - ");
Console.WriteLine(sb.ToString());
Output:
Welcome - Hello C#
Key Points:
-
StringBuilderis mutable. -
It belongs to the
System.Textnamespace. -
It is efficient for repeated string modifications.
-
It reduces intermediate string allocations.
-
It maintains an internal buffer that can grow.
-
It is not thread-safe for concurrent modifications.
-
ToString()returns a regularstring.
3. What is StringBuffer? Does C# support it?
StringBuffer is a mutable string class available in Java, not in the standard .NET libraries.
In Java, StringBuffer provides synchronized methods, making individual operations thread-safe.
Java Example:
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
System.out.println(sb.toString());
Output:
Hello World
Does C# have an equivalent?
C# does not provide a direct built-in equivalent of Java's synchronized StringBuffer.
Instead, C# developers generally use StringBuilder and apply synchronization when multiple threads must modify the same instance.
For example:
using System.Text;
StringBuilder sb = new StringBuilder();
object lockObject = new object();
lock (lockObject)
{
sb.Append("Hello");
sb.Append(" World");
}
All threads accessing the shared builder must use the same lock to ensure synchronized access.
Key Points:
-
StringBufferbelongs to Java. -
It is mutable.
-
Its methods are synchronized.
-
C# does not have a built-in
StringBuffer. -
C# uses
StringBuilderwith explicit synchronization when required.
2. Comparison: string vs StringBuilder vs StringBuffer
|
Feature |
|
|
|
|---|---|---|---|
|
Language |
C# / Java |
C# / Java |
Java |
|
Supported in C# |
Yes |
Yes |
No |
|
Mutable |
No |
Yes |
Yes |
|
Thread safety |
Immutable contents |
Not thread-safe |
Synchronized methods |
|
Repeated modifications |
Can be costly |
Generally efficient |
Generally efficient |
|
Memory allocation |
May create new strings |
Reuses internal buffers |
Reuses internal buffers |
|
Best usage |
Fixed text |
Frequently changing text |
Synchronized text operations in Java |
3. Performance Example – string vs StringBuilder
Consider generating a large report with 10,000 lines.
Using string:
string result = "";
for (int i = 0; i < 10000; i++)
{
result += "Employee Record\n";
}
This repeatedly concatenates strings, potentially allocating many intermediate objects.
Using StringBuilder:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.AppendLine("Employee Record");
}
string result = sb.ToString();
StringBuilder generally performs better for this pattern because it avoids allocating a new string for every iteration.
Memory and performance flow
Using string
------------
"Employee"
|
v
"Employee Record"
|
v
"Employee Record 1"
|
v
"Employee Record 1 2"
Repeated concatenation
|
v
Multiple string allocations
Using StringBuilder
-------------------
StringBuilder Object
|
v
Internal Buffer
|
+---- Append()
|
+---- Append()
|
+---- Append()
|
v
Final Content
|
v
ToString()
Fewer intermediate string allocations
Note that StringBuilder can still allocate memory when its capacity grows.
4. Real-World Scenario in ASP.NET Core
Suppose you are generating a formatted email body or a large text report.
using System.Text;
public string GenerateEmployeeReport()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Employee Report");
sb.AppendLine("----------------");
for (int i = 1; i <= 1000; i++)
{
sb.AppendLine($"Employee ID: {i}");
}
return sb.ToString();
}
Why use StringBuilder here?
Because the report is constructed through many repeated append operations. Using StringBuilder reduces unnecessary intermediate string allocations.
For small messages with only a few concatenations, a regular string is usually simpler and sufficiently efficient.
5. Important Interview Key Points
-
stringis immutable, whileStringBuilderis mutable. -
Both
stringandStringBuilderare reference types in C#. -
StringBuilderis generally preferable for repeated modifications inside loops. -
stringis suitable for fixed text and a small number of concatenations. -
StringBuilderis not inherently thread-safe. -
StringBufferis a Java class and is not built into C#. -
Immutability makes a
stringobject's contents safe to share between threads, although variable assignments still require appropriate synchronization. -
StringBuilder.ToString()returns an immutable string.
6. Interview Question: Which one should you use?
Answer:
I use string for normal text operations because it is immutable, simple, and easy to maintain.
When an application requires frequent string modifications, especially inside loops or while generating large reports, I prefer StringBuilder because it reduces intermediate string allocations and generally improves performance.
C# does not support Java's built-in StringBuffer. If thread-safe modifications are required, I use StringBuilder with appropriate synchronization.
Final takeaway:
Need to store normal text?
|
v
string
Need repeated modifications?
|
v
StringBuilder
Need concurrent modifications
to a shared builder?
|
v
StringBuilder + lock
StringBuffer?
|
v
Java (not built into C#)