C#
programming
List<T>
repetition
coding techniques

Shortest way to create a ListT of a repeated element

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The shortest way to create a List<T> of repeated elements in C# is Enumerable.Repeat(element, count).ToList(). This one-liner from LINQ creates a sequence containing the specified element repeated the given number of times, then materializes it as a List<T>. For value types, each element is an independent copy. For reference types, all entries point to the same object. Alternatives include array initialization with new T[count] (for default values), list comprehension with Enumerable.Range, and manual loops.

csharp
1using System.Linq;
2
3// Repeat an integer
4List<int> zeros = Enumerable.Repeat(0, 10).ToList();
5// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
6
7// Repeat a string
8List<string> hellos = Enumerable.Repeat("hello", 5).ToList();
9// ["hello", "hello", "hello", "hello", "hello"]
10
11// Repeat a boolean
12List<bool> flags = Enumerable.Repeat(true, 3).ToList();
13// [true, true, true]
14
15// Repeat a custom struct
16List<(int x, int y)> points = Enumerable.Repeat((0, 0), 4).ToList();
17// [(0,0), (0,0), (0,0), (0,0)]

Enumerable.Repeat is lazy — it does not allocate the full list until .ToList() is called.

Enumerable.Range with Select

When each element needs to be a new instance (important for reference types):

csharp
1// Each element is a NEW List<int> instance
2List<List<int>> matrix = Enumerable.Range(0, 5)
3    .Select(_ => new List<int>())
4    .ToList();
5
6// Now modifying one does NOT affect others
7matrix[0].Add(42);
8Console.WriteLine(matrix[1].Count); // 0 — independent
9
10// Compare with Repeat (WRONG for reference types):
11List<List<int>> shared = Enumerable.Repeat(new List<int>(), 5).ToList();
12shared[0].Add(42);
13Console.WriteLine(shared[1].Count); // 1 — same object!

Array Initialization

For default values, array creation is the fastest approach:

csharp
1// Default value arrays
2int[] zeros = new int[100];           // All 0
3bool[] falses = new bool[100];        // All false
4string[] nulls = new string[100];     // All null
5
6// Convert to List<T>
7List<int> zeroList = new List<int>(new int[100]);
8
9// Fill with a specific value
10int[] fives = new int[100];
11Array.Fill(fives, 5);
12List<int> fiveList = new List<int>(fives);

Manual Loop

Simple and explicit, useful when you need complex initialization logic:

csharp
1// Basic loop
2var list = new List<int>(capacity: 100); // Pre-allocate capacity
3for (int i = 0; i < 100; i++)
4{
5    list.Add(42);
6}
7
8// With factory function for reference types
9var items = new List<MyClass>(capacity: 10);
10for (int i = 0; i < 10; i++)
11{
12    items.Add(new MyClass { Id = i });
13}

Collection Expressions (C# 12)

C# 12 introduces collection expressions with spread:

csharp
1// Small fixed lists
2List<int> small = [1, 1, 1, 1, 1];
3
4// For repeated elements, Enumerable.Repeat is still cleaner
5List<int> repeated = [.. Enumerable.Repeat(42, 10)];

Performance Comparison

csharp
1using System.Diagnostics;
2
3const int count = 1_000_000;
4
5// Enumerable.Repeat — clean, moderate speed
6var sw = Stopwatch.StartNew();
7var list1 = Enumerable.Repeat(42, count).ToList();
8Console.WriteLine($"Repeat: {sw.ElapsedMilliseconds}ms");
9
10// Array + Fill — fastest
11sw.Restart();
12var arr = new int[count];
13Array.Fill(arr, 42);
14var list2 = new List<int>(arr);
15Console.WriteLine($"Array.Fill: {sw.ElapsedMilliseconds}ms");
16
17// Loop with pre-allocated capacity — fast
18sw.Restart();
19var list3 = new List<int>(count);
20for (int i = 0; i < count; i++) list3.Add(42);
21Console.WriteLine($"Loop: {sw.ElapsedMilliseconds}ms");
MethodReadabilityPerformanceReference Type Safe
Enumerable.Repeat().ToList()BestGoodNo (shared reference)
Enumerable.Range().Select()GoodGoodYes (new instances)
new int[n] + Array.FillModerateBestN/A (value types)
Manual loopModerateGoodYes (if using new)

Common Pitfalls

  • Using Enumerable.Repeat with reference types: All elements point to the same object. Modifying one element modifies all. Use Enumerable.Range(0, n).Select(_ => new T()) to create independent instances.
  • Not pre-allocating list capacity in loops: new List<int>() starts with capacity 0 and resizes as elements are added. For known sizes, pass the capacity to the constructor: new List<int>(count).
  • Confusing Enumerable.Repeat with string constructor: new string('x', 5) creates "xxxxx" (a string), not a list. For a List<char>, use Enumerable.Repeat('x', 5).ToList().
  • Forgetting .ToList() after Enumerable.Repeat: Enumerable.Repeat returns an IEnumerable<T>, not a List<T>. Without .ToList(), you get a lazy sequence that is re-evaluated each time it is enumerated.
  • Using Enumerable.Repeat(new int[3], 5) expecting independent arrays: This creates 5 references to the same array. Mutating one array mutates all five. Use Enumerable.Range(0, 5).Select(_ => new int[3]) instead.

Summary

  • Enumerable.Repeat(value, count).ToList() is the shortest and most readable approach
  • For reference types, use Enumerable.Range(0, n).Select(_ => new T()) to create independent instances
  • For maximum performance with value types, use new T[n] with Array.Fill
  • Pre-allocate List<T> capacity when the size is known in advance
  • C# 12 collection expressions support spread: [.. Enumerable.Repeat(x, n)]

Course illustration
Course illustration

All Rights Reserved.