Back to Blog
C#

C# List Initialization: Syntax, Examples, and Performance

c# list initialization: Learn C# list initialization with collection initializers, LINQ, and performance considerations for efficient code in your applications.

C#List<T>Collection InitializersLINQPerformance
Illustration of C# list initialization showing different syntax patterns and a list icon.

In C#, initializing a list is a common operation that appears in almost every application. The way you initialize a List<T> affects readability, memory usage, and even runtime performance. This article covers the primary syntax for C# list initialization, from simple constructors to collection initializers and LINQ-based approaches.

Basic List Initialization with the Constructor

List<T> has a parameterless constructor that creates an empty list. You then add items individually.

List<string> names = new List<string>(); names.Add("Alice"); names.Add("Bob");

This is the most straightforward approach but requires multiple statements. For a small fixed set, collection initializers are more concise.

Collection Initializer Syntax

C# provides a collection initializer that lets you specify elements directly in the constructor call:

List<int> numbers = new List<int> { 1, 2, 3, 4 };

The compiler translates this into repeated calls to Add. This works for any type that implements IEnumerable and has an Add method. For List<T>, it's syntactic sugar.

You can also use collection initializers with object initializers for custom types:

List<Person> people = new List<Person> { new Person { Name = "Alice", Age = 30 }, new Person { Name = "Bob", Age = 25 } };

This is common when building test data or configuring in-memory collections.

Initializing from an Existing Collection

If you already have an array or another collection, you can pass it to the List<T> constructor:

int[] array = { 1, 2, 3 }; List<int> list = new List<int>(array);

The constructor copies the elements. This is efficient for arrays because it uses Array.Copy internally. For other IEnumerable<T> sources, it may enumerate and add.

Using LINQ to Generate a List

LINQ provides ToList() to materialize a query into a List<T>. This is useful when you need to transform or filter data:

List<int> squares = Enumerable.Range(1, 5).Select(x => x * x).ToList();

Enumerable.Range generates a sequence, Select transforms it, and ToList creates the list. This is a functional approach that can be more readable for complex transformations.

Performance Considerations for List Initialization

When you know the number of elements in advance, you can set the initial capacity to avoid resizing. List<T> uses an internal array that doubles when full. Repeated resizing copies the entire array, which is O(n) each time.

List<int> numbers = new List<int>(1000);

This allocates an array of 1000 slots immediately. If you later add 1000 items, no resizing occurs. This is a measurable improvement when the list is large.

For collection initializers, the compiler uses the default capacity (0) and grows as needed. If you have a large fixed set, consider using the constructor with capacity or an array.

Common Mistakes and Edge Cases

  • Forgetting to initialize a list before adding items: List<T> is a reference type; a null list throws NullReferenceException.
  • Using collection initializers on a read-only property: the initializer calls Add on the existing list, so it works only if the property is initialized.
  • Assuming ToList() copies the original collection: it creates a new list, so modifications don't affect the source.
  • Using new List<T>() without capacity for a known large size: causes unnecessary reallocations.

Choosing the Right Initialization Approach

The choice depends on the context:

  • Use collection initializers for small, fixed sets that are known at compile time.
  • Use the constructor with an existing collection when you already have an array or IEnumerable<T>.
  • Use LINQ ToList() when you need to transform or filter data.
  • Use capacity when you know the exact or approximate size and performance matters.

There is no single "best" way; the right choice balances readability and performance.

c# list initialization: Practical Usage and Code Examples | RYUSLOG DEV