I was recently inspired by some interesting performance characteristics for collection initializers and collection expressions in C#, and I wanted to put together an introductory article. This article will be part of a small series where I first introduce you to the syntax we have to work with for both collection expressions and collection initializers in C#. We’ll see the difference in style and readability — which the dotnet team has been progressing to make the language feel less heavy-handed while still maintaining expressiveness. Once you’ve got a feel for how collection initializers and collection expressions in C# work, you’ll be geared up to check out some of the performance benchmarks on them. There’s no point in hyper-optimizing for this stuff unless you understand the basics! Using List<T> with Collection Initializers in C# Collection initializers in C# allow for a concise and readable way to populate collections like upon instantiation. This feature simplifies code by enabling the initialization of a collection with a set of predefined elements without the need for multiple calls to the method. List<T> Add These next subsections will show examples of collection initializers with the type. Keep in mind that the entire point of these initializers is to define collections with elements in them to start with, which would save us from doing something like the following: List<T> List<string> devLeaderCoolList = new List<string>(); devLeaderCoolList.Add("Hello"); devLeaderCoolList.Add(", "); devLeaderCoolList.Add("World!"); So, with this as a starting point, consider that the upcoming examples will make this feel more streamlined and concise. Example 1: Initializing a List of Integers List<int> primeNumbers = new List<int> { 2, 3, 5, 7, 11, 13, 17 }; This example demonstrates initializing a with a collection of prime numbers. The numbers are enclosed in braces and separated by commas, directly following the instantiation of the list. List<int> {} We can also use a slightly more short-hand syntax to drop the entire duplicated type definition from the right side of the equal sign: List<int> primeNumbers = new() { 2, 3, 5, 7, 11, 13, 17 }; Example 2: Combining Object and Collection Initializers public class Student { public string Name { get; set; } public int Age { get; set; } } List<Student> students = new List<Student> { new Student { Name = "Alice", Age = 22 }, new Student { Name = "Bob", Age = 24 } }; Here, we combine object and collection initializers to create a where each object is initialized with and properties. This approach streamlines the process of filling a collection with fully initialized objects. The important thing to pay attention to here is that the object initializer syntax is very much like the collection initializer syntax, but we are indeed doing two things: List<Student> Student Name Age Assigning values to properties of new objects Assigning the collection elements upon collection creation Example 3: Using Complex Expressions List<double> areas = new List<double> { Math.PI * Math.Pow(3, 2), Math.PI * Math.Pow(5, 2) }; This example initializes a with areas of circles (using ), where is the radius. It illustrates that expressions, including method calls, can be used within collection initializers — that is, there is no restriction on constants or pre-evaluated values. List<double> πr² r Example 4: Nested Collection Initializers public class Classroom { public List<Student> Students { get; set; } } List<Classroom> classrooms = new List<Classroom> { new Classroom { Students = new List<Student> { new Student { Name = "Alice", Age = 22 } } }, new Classroom { Students = new List<Student> { new Student { Name = "Bob", Age = 24 } } } }; This example shows how to use nested collection initializers to initialize a list of objects, each containing a list of objects. It is very much like Example 2, which we have already looked at, but this takes things up one more notch, showing multiple collection initializers and object initialization. Classroom Student Example 5: Simple List Initialization with Collection Expressions . This was a step forward in reducing the verbosity of collection declarations using more shorthand, similar to other languages. Microsoft says in its documentation: In C# 11, we start to get some new fancier syntax for collection expressions You can use a to create common collection values. A is a terse syntax that, when evaluated, can be assigned to many different collection types. A collection expression contains a sequence of elements between and brackets. collection expression collection expression [ ] Microsoft Let’s check out an example: List<int> evenNumbers = [2, 4, 6, 8, 10]; This example demonstrates the straightforward initialization of a using the new collection expressions syntax, making the code more concise and readable. List<int> Example 6: Combining Collections with Spread Operator And there are even more goodies in : C# 12 — we get the spread operator for collection initialization List<int> firstBatch = [1, 2, 3]; List<int> combinedList = [0, ..firstBatch, 4]; Here, the spread operator is used to include elements from an existing collection ( ) into a new list, showcasing the flexibility of the new syntax in combining collections seamlessly. .. firstBatch Where Are We Headed With These? As you read through the various code examples, you can decide for yourself which ones offer you the readability that you prefer. There’s not necessarily a right or wrong answer here, but with variety and choice, we are likely going to need to make decisions within our teams about how to stay consistent. Try to strike a balance between minimizing redundancy without hiding too much type information! But what’s next? Do we care THAT much about readability? I mean, I do. Honestly, I think it’s incredibly important to prioritize readability in code. But if you’re curious like me, you might see a post like this from on the interwebs and get very curious: Dave Callan And since this is what sparked my interest and caused me to write this article as a primer, you’ll perhaps be interested in the performance characteristics that I investigated! Wrapping Up C# Collection Initializers and Collection Expressions Now that you’ve seen various examples of the syntax that we have access to, you can make your own informed decisions about which are most readable to you. I think it’s always important to spend some time looking at alternatives so that you can understand different perspectives, even if it seems like the differences might be minor. Odds are you’re going to read and write collection initializers and collection expressions MANY times in your software engineering career, so why not optimize your choice? Speaking of optimizations… wait until you see ! the next article on the performance of collection initializers If you found this useful and you’re looking for more learning opportunities, consider and check out my ! subscribing to my free weekly software engineering newsletter free videos on YouTube Also published . here