C# - List<T>

You have already learned about ArrayList in the previous section. An ArrayList resizes automatically as it grows. The List<T> collection is the same as an ArrayList except that List<T> is a generic collection whereas ArrayList is a non-generic collection.

The following diagram illustrates the List<T> hierarchy.

C# generic list

As shown in the above diagram, the List<T> class implements eight different interfaces that provide different functionalities. Hence, the List<T> object can be assigned to any of its interface type variables. However, it is recommended to create an object of List<T> and assign it to IList<T> or List<T> type variable, as shown below.

Example: List<T>
List<int> intList = new List<int>();

//Or

IList<int> intList = new List<int>();

In the above example, the first statement uses List<T> type variable, whereas the second statement uses IList<T> type variable. The List<T> is a concreate implementation of IList<T> interface. In the object-oriented programming, it is advisable to program to interface rather than concreate class. So use IList<T> type variable to create an object of List<T>.

However, List<T> includes more helper methods than IList<T> interface. The following table lists the important properties and methods of List<T> class:

Property Usage
Items Gets or sets the element at the specified index
Count Returns the total number of elements exists in the List<T>
Method Usage
Add Adds an element at the end of a List<T>.
AddRange Adds elements of the specified collection at the end of a List<T>.
BinarySearch Search the element and returns an index of the element.
Clear Removes all the elements from a List<T>.
Contains Checks whether the speciied element exists or not in a List<T>.
Find Finds the first element based on the specified predicate function.
Foreach Iterates through a List<T>.
Insert Inserts an element at the specified index in a List<T>.
InsertRange Inserts elements of another collection at the specified index.
Remove Removes the first occurence of the specified element.
RemoveAt Removes the element at the specified index.
RemoveRange Removes all the elements that match with the supplied predicate function.
Sort Sorts all the elements.
TrimExcess Sets the capacity to the actual number of elements.
TrueForAll Determines whether every element in the List<T> matches the conditions defined by the specified predicate.

Add Elements into List

Use the IList.Add() method to add an element into a List collection. The following example adds int value into a List<T> of int type.

Add() signature: void Add(T item)

Example: Adding elements into List
IList<int> intList = new List<int>();
intList.Add(10);
intList.Add(20);
intList.Add(30);
intList.Add(40);

IList<string> strList = new List<string>();
strList.Add("one");
strList.Add("two");
strList.Add("three");
strList.Add("four");
strList.Add("four");
strList.Add(null);
strList.Add(null);

IList<Student> studentList = new List<Student>();
studentList.Add(new Student());
studentList.Add(new Student());
studentList.Add(new Student());

You can also add elements at the time of initialization using object initializer syntax as below:

Example: Add elements using object initializer syntax
IList<int> intList = new List<int>(){ 10, 20, 30, 40 };

//Or

IList<Student> studentList = new List<Student>() { 
                new Student(){ StudentID=1, StudentName="Bill"},
                new Student(){ StudentID=2, StudentName="Steve"},
                new Student(){ StudentID=3, StudentName="Ram"},
                new Student(){ StudentID=1, StudentName="Moin"}
            };

AddRange()

Use List.AddRange() method adds all the elements from another collection.

AddRange() signature: void AddRange(IEnumerable<T> collection)

Example: AddRange
IList<int> intList1 = new List<int>();
intList1.Add(10);
intList1.Add(20);
intList1.Add(30);
intList1.Add(40);

List<int> intList2 = new List<int>();

intList2.AddRange(intList1);
 
Note : The AddRange() method will only be applicable if you initialized with a List<T> variable. IList<T> doesn't include the AddRange() method.

Accessing List

Use a foreach or for loop to iterate a List<T> collection.

Example: Accessing List
List<int> intList = new List<int>() { 10, 20, 30 };

intList.ForEach(el => Console.WriteLine(el));

If you have initialized the List<T> with an IList<T> interface then use seperate foreach statement with implicitly typed variable:

Example: Accessing List
IList<int> intList = new List<int>() { 10, 20, 30, 40 };

foreach (var el in intList)
    Console.WriteLine(el);
Output:
10
20
30
40

Access individual items by using an indexer (i.e., passing an index in square brackets):

Example: Accessing List
IList<int> intList = new List<int>() { 10, 20, 30, 40 };

int elem = intList[1]; // returns 20

Use the Count property to get the total number of elements in the List.

Example: Access List elements
IList<int> intList = new List<int>() { 10, 20, 30, 40 };

Console.Write("Total elements: {0}", intList.Count);
Output:
Total elements: 4

Use for loop to access list as shown below:

Example: Accessing List using for loop example:
IList<int> intList = new List<int>() { 10, 20, 30, 40 };

for (int i = 0; i < intList.Count; i++)
    Console.WriteLine(intList[i]);

List<T> implements IList<T>, so List<T> implicitly type cast to IList<T>.

Example: Access List
static void Print(IList<string> list)
{
    Console.WriteLine("Count: {0}", list.Count);
    foreach (string value in list)
    {
        Console.WriteLine(value);
    }
}

static void Main(string[] args)
{

    string[] strArray = new string[2];
    strArray[0] = "Hello";
    strArray[1] = "World";
    Print(strArray);

    List<string> strList = new List<string>();
    strList.Add("Hello");
    strList.Add("World");
    Print(strList);
}
Output:
Hello
World
Hello
World

Insert Elements into List

Use the IList.Insert() method inserts an element into a List<T> collection at the specified index.

Insert() signature:void Insert(int index, T item);

Example: Insert elements into List
IList<int> intList = new List<int>(){ 10, 20, 30, 40 };

intList.Insert(1, 11);// inserts 11 at 1st index: after 10.

foreach (var el in intList)
    Console.Write(el);
Output:
10
11
20
30
40

Remove Elements from List

The Remove() and RemoveAt() methods to remove items from a List<T> collection.

Remove() signature: bool Remove(T item)

RemoveAt() signature: void RemoveAt(int index)

Example: Remove elements from List
IList<int> intList = new List<int>(){ 10, 20, 30, 40 };

intList.Remove(10); // removes the 10 from a list

intList.RemoveAt(2); //removes the 3rd element (index starts from 0)

foreach (var el in intList)
    Console.Write(el);
Output:
20
30

TrueForAll()

The TrueForAll() is a method of the List<T> class that returns true if the specified condition turns out to be true, otherwise false. Here, the condition can be specified as the predicate type deligate or the lambda expression.

TrueForAll() signature: bool TrueForAll(Predicate<T> match)

Example: TrueForAll()
List<int> intList = new List<int>(){ 10, 20, 30, 40 };

bool res = intList.TrueForAll(el => el%2 == 0);// returns true

The following example uses isPositiveInt() as a Predicate<int> type delegate as a parameter to TrueForAll.

Example: TrueForAll()
static bool isPositiveInt(int i)
{
    return i > 0;
}

static void Main(string[] args)
{
    List<int> intList = new List<int>(){10, 20, 30, 40};

    bool res = intList.TrueForAll(isPositiveInt);
}

Visit MSDN to for more information on the methods & properties of IList<T> or List<T>.

Points to Remember :
  1. List<T> stores elements of the specified type and it grows automatically.
  2. List<T> can store multiple null and duplicate elements.
  3. List<T> can be assigned to IList<T> or List<T> type of variable. It provides more helper method When assigned to List<T> variable
  4. List<T> can be access using indexer, for loop or foreach statement.
  5. LINQ can be use to query List<T> collection.
  6. List<T> is ideal for storing and retrieving large number of elements.