Question
In C#, what is the best way to generate a string made of repeated tab characters?
I am learning C# and experimenting with different ways to express the same idea. I want a method Tabs(uint numTabs) that returns a string containing numTabs tab characters.
For example:
Tabs(3) // returns "\t\t\t"
Which of the following implementations is best?
I understand that the answer depends on what “best” means. For example:
- The LINQ version is short, but does calling
RepeatandAggregateadd unnecessary overhead? - The
StringBuilderversion is very clear, but isStringBuilderslower in this case? - The plain string version is simple and easy to understand.
- Or does it not matter much at all?
These questions are mainly to help me build intuition about how C# works.
private string Tabs(uint numTabs)
{
IEnumerable<string> tabs = Enumerable.Repeat("\t", (int)numTabs);
return (numTabs > 0) ? tabs.Aggregate((sum, next) => sum + next) : "";
}
private string Tabs(uint numTabs)
{
StringBuilder sb = new StringBuilder();
for (uint i = 0; i < numTabs; i++)
sb.Append("\t");
return sb.ToString();
}
private string Tabs(uint numTabs)
{
string output = "";
for (uint i = 0; i < numTabs; i++)
{
output += '\t';
}
return output;
}
Short Answer
By the end of this page, you will understand how repeated string creation works in C#, why some approaches are more efficient than others, and which option is usually best for repeating a character such as \t. You will also learn when StringBuilder is useful, why repeated string += can become expensive, and which built-in APIs make this task simplest.
Concept
In C#, string objects are immutable. That means once a string is created, it cannot be changed. If you write code like this:
output += '\t';
a new string is created each time through the loop.
That matters because building a string one piece at a time with += can become inefficient. Each concatenation may copy the old contents into a new string, then add the new character.
For a small number of tabs, this usually does not matter much. But for larger counts, it can become much slower and use more memory.
Why StringBuilder exists
StringBuilder is designed for cases where you build a string gradually. Instead of creating a brand-new string for every append, it keeps a mutable internal buffer and grows it as needed.
That makes it a better choice than repeated += when:
- you are appending inside a loop
- you do not know the final string up front
- the result may be large
Why the LINQ version is not ideal here
LINQ is great for querying collections, but this problem is not really a collection-query problem. Using:
Enumerable.Repeat- then
Aggregate
adds extra abstraction and overhead for something very simple. Also, still performs repeated string concatenation, so it does not avoid the core inefficiency.
Mental Model
Think of a string like text carved into stone.
- If you want to add one more character, you cannot change the stone.
- You must carve a new stone with all the old text plus the new character.
That is what happens with repeated string +=.
Now think of StringBuilder like writing on a whiteboard.
- You can keep adding characters without recreating everything each time.
- When you are done, you copy the final result into a string.
And think of new string('\t', count) like ordering a pre-made rope of exactly the right length.
- You already know the character
- You already know how many times it should repeat
- So the runtime can create the final result directly
That is why it is usually the cleanest option for this case.
Syntax and Examples
If you want to repeat a single character in C#, the most direct syntax is:
string tabs = new string('\t', 3);
Console.WriteLine(tabs.Length); // 3
Recommended approach
private string Tabs(int numTabs)
{
return new string('\t', numTabs);
}
Example:
Console.WriteLine(Tabs(3) == "\t\t\t"); // True
This is usually the best solution because it is:
- short
- readable
- efficient
Using StringBuilder
If you need to build text in multiple steps, use StringBuilder:
using System.Text;
private ()
{
StringBuilder sb = StringBuilder(numTabs);
( i = ; i < numTabs; i++)
{
sb.Append();
}
sb.ToString();
}
Step by Step Execution
Consider this example:
string result = new string('\t', 4);
What happens step by step
- The character
\tis chosen as the content to repeat. - The count
4tells C# how many times to repeat it. - The runtime allocates a string of length 4.
- Each position is filled with a tab character.
- The final string is returned.
The result is equivalent to:
"\t\t\t\t"
Compare with +=
string output = "";
for (int i = 0; i < 4; i++)
{
output += '\t';
}
Trace:
- Start:
output = "" - After loop 1:
"\t" - After loop 2:
"\t\t" - After loop 3:
Real World Use Cases
Repeating characters or short strings appears in many real programs.
Indentation and formatting
Your tabs example is common when generating:
- formatted console output
- source code
- XML or JSON-like text
- nested debug output
string indent = new string('\t', depth);
Console.WriteLine(indent + "Node");
Padding output
You may repeat spaces or symbols to align text:
string line = new string('-', 20);
Console.WriteLine(line);
Generating separators
string border = new string('=', 40);
Useful for logs, reports, and command-line tools.
Creating test data
When testing string-processing code, developers often generate repeated input:
string sample = new string(, );
Real Codebase Usage
In real projects, developers usually choose the tool based on the shape of the problem.
Common pattern: direct character repetition
If the task is exactly “repeat one character N times”, developers typically use:
string indent = new string('\t', level);
This is common in:
- pretty-printers
- text exporters
- log formatters
- code generators
Common pattern: build a larger string with many parts
When repeated characters are only one part of a larger output, developers often use StringBuilder:
var sb = new StringBuilder();
sb.Append(new string('\t', level));
sb.AppendLine("Item");
Validation and guard clauses
In production code, developers often validate counts before constructing strings:
private string Tabs(int numTabs)
{
if (numTabs < 0)
throw ArgumentOutOfRangeException((numTabs));
(, numTabs);
}
Common Mistakes
1. Using += inside a loop for large strings
Broken or inefficient pattern:
string output = "";
for (int i = 0; i < 10000; i++)
{
output += '\t';
}
Why it is a problem:
- each concatenation creates a new string
- performance gets worse as the string grows
Better:
string output = new string('\t', 10000);
or, for more complex output:
var sb = new StringBuilder();
2. Using LINQ for simple string repetition
var tabs = Enumerable.Repeat("\t", count);
string result = tabs.Aggregate((a, b) => a + b);
Why it is not ideal:
- more complex than necessary
- still performs repeated concatenation
- less readable for this specific task
Better:
Comparisons
| Approach | Example | Readability | Performance | Best for |
|---|---|---|---|---|
new string(char, count) | new string('\t', 3) | High | Excellent | Repeating one character |
StringBuilder | sb.Append('\t') in a loop | High | Very good | Building larger strings in steps |
string += in loop | output += '\t'; | Medium | Poor for large counts | Tiny examples or teaching basics |
LINQ Repeat + |
Cheat Sheet
Best option for repeating one character
string tabs = new string('\t', count);
Recommended method
private string Tabs(int numTabs)
{
if (numTabs < 0)
throw new ArgumentOutOfRangeException(nameof(numTabs));
return new string('\t', numTabs);
}
When to use what
- Use
new string(char, count)for one repeated character - Use
StringBuilderfor many appends or complex text generation - Avoid
string +=in loops for large strings - Avoid LINQ for this simple repetition task
Key rule
string is immutable in C#.
That means:
output += ;
FAQ
What is the fastest way to repeat a character in C#?
Usually new string(char, count) is the fastest and clearest way when you need one character repeated many times.
Is StringBuilder faster than string concatenation?
Yes, usually when you append repeatedly in a loop. StringBuilder avoids creating a new string on every append.
Is LINQ a good choice for repeating a string in C#?
Not usually for this problem. It is more verbose internally and less efficient than the direct new string solution.
Why is string += in a loop slow?
Because strings are immutable. Every concatenation creates a new string and copies existing content.
Should I use uint for counts that cannot be negative?
Usually no. Most .NET APIs use int, so using uint often makes code less convenient and requires casts.
What happens if the repeat count is 0?
new string('\t', 0) returns an empty string.
Can StringBuilder still be the right choice here?
Yes, if tabs are only one small part of a larger string you are constructing step by step.
Mini Project
Description
Create a small formatting helper for console output that generates indentation and section separators. This demonstrates when new string(char, count) is the simplest tool and when it can be combined with other string-building patterns.
Goal
Build a helper that prints a simple tree-like report using repeated tabs and repeated separator characters.
Requirements
- Create a method that returns
ntab characters. - Create a method that returns a separator line made of
-characters. - Print at least three lines with different indentation levels.
- Handle zero correctly so no tabs or separators are added when the count is 0.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
C# Array Initialization Syntaxes Explained
Learn all common C# array initialization syntaxes with examples, rules, comparisons, and mistakes beginners often make.
C# Type Checking Explained: typeof vs GetType() vs is
Learn when to use typeof, GetType(), and is in C#. Understand exact type checks, inheritance, and safe type testing clearly.