
A List can be initialized in many ways. Each element can be added in a loop with the Add method. Alternatively a special initializer syntax form can be used. Objects inside the List can be initialized in this syntax form. Most syntax forms are compiled to the same intermediate representation.
These C# examples show how to intialize Lists with different syntax forms.

First, although the C# language has many different ways to populate a List with values, many of them are compiled into the same machine code before runtime. The example below shows how you can use the curly brackets and add elements in these expressions ('list1' and 'list2').
You can also use an array to initialize a List, or even assign existing elements in a List. The example also shows how you can simply populate the list imperatively with Add.
Program that initializes string list [C#]
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Use collection initializer.
List<string> list1 = new List<string>()
{
"carrot",
"fox",
"explorer"
};
// Use var keyword with collection initializer.
var list2 = new List<string>()
{
"carrot",
"fox",
"explorer"
};
// Use new array as parameter.
string[] array = { "carrot", "fox", "explorer" };
List<string> list3 = new List<string>(array);
// Use capacity in constructor and assign.
List<string> list4 = new List<string>(3);
list4.Add(null); // Add empty references. (BAD)
list4.Add(null);
list4.Add(null);
list4[0] = "carrot"; // Assign those references.
list4[1] = "fox";
list4[2] = "explorer";
// Use Add method for each element.
List<string> list5 = new List<string>();
list5.Add("carrot");
list5.Add("fox");
list5.Add("explorer");
// Make sure they all have the same number of elements.
Console.WriteLine(list1.Count);
Console.WriteLine(list2.Count);
Console.WriteLine(list3.Count);
Console.WriteLine(list4.Count);
Console.WriteLine(list5.Count);
}
}
Output
3
3
3
3
3
Collection initializer statements. The first two declarations in the Main entry point show how you can specify three strings to be initially added to the List collection when it it is instantiated. The first two statements are equivalent to the final statement using 'list5', with only a small difference in the intermediate language. The Add method is called repeatedly on the values in the braces.

Using array parameter. The part of the example that initializes 'list3' copies an external array to the internal buffer of the List at runtime. This avoids unnecessary resizing of the List buffer because the element count it known before any Add methods are executed.
Other initializations. The example C# code also shows a very bad example of initializing a List in the normal case (list4). This initialize shows that you can Add any references and then modify the value of those references when initializing your List. This is useful in non-trivial methods, and the example here is poor programming practice.

You can allocate and assign the properties of objects inline with the List initialization. In the C# language, object initializers and collection initializers share similar syntax but have different purposes. An object initializer sets the individual fields in the object such as properties, while a collection initializer sets the elements in the collection, not fields. This example shows an object that has two properties A and B, and the properties are set in the List initializer.
Program that initializes object Lists [C#]
using System;
using System.Collections.Generic;
class Test // Used in Lists.
{
public int A { get; set; }
public string B { get; set; }
}
class Program
{
static void Main()
{
// Initialize list with collection initializer.
List<Test> list1 = new List<Test>()
{
new Test(){ A = 1, B = "Jessica"},
new Test(){ A = 2, B = "Mandy"}
};
// Initialize list with new objects.
List<Test> list2 = new List<Test>();
list2.Add(new Test() { A = 3, B = "Sarah" });
list2.Add(new Test() { A = 4, B = "Melanie" });
// Write number of elements in the lists.
Console.WriteLine(list1.Count);
Console.WriteLine(list2.Count);
}
}
Output
2
2Assigning property syntax. The example shows how you can assign a property in an object instance such as the 'Test' object using the property's name and the equals operator. So in the initialization of 'list1', two Test instances are allocated with the A properties of 1 and 2 and the B properties of Jessica and Mandy.

The C# compiler, which is run before your program is ever executed, parses the initializer tokens { } and turns them into individual Add method calls on the List. This is true for any List initializer, both those in the first example program and the second example program. Essentially, the compiler transforms your expression-based declarations into Add method calls. The performance at runtime is equivalent.
List Add Method
When reflecting into programs that use collection initializers such as with List or arrays, you will be surprised to see extra temporary variables being created on the method stack. At runtime, these excess opcodes are eliminated and cause no performance loss.
The C# language specification states that these temporary variables are used to simplify the process of definite assignment analysis, which is how the compiler proves you are always using initialized memory. See "The C# Programming Language Third Edition, Special Annotated Edition" page 266.
The C# Programming Language: SpecificationWe looked into some specifics on List initializations in the C# language, first seeing how you can initialize string List collections using the expression-based syntax and also the copy constructor and Add method. Next we saw how you can apply object initializers with List initializations for terse syntax in object Lists. Finally, we noted the implementation specifics of List initialization and also how it affects definite assignment analysis.
Initialize Array Collections