C# List

Array Collections File Keyword String .NET Cast Class Data Dictionary Enum Exception If Interface Lambda LINQ List Loop Method Number Process Property Regex Sort Split StringBuilder Struct Substring Switch Time Windows

List

List. An array does not dynamically resize. A List does. With it, we do not need to manage the size on our own. This type is ideal for linear collections not accessed by keys.


List

Dynamic in size, with many methods, List makes life easier. List is a generic (constructed) type. We need to use < and > in the List declaration. Lists handle any element type.


Copyright

First, we declare a List of int values. We create a new List of unspecified size and adds four prime numbers to it. Values are stored in the order added.

Note:There are other ways to create, and add elements to, Lists—this is not the simplest.

Tip:The angle brackets are part of the declaration type. They are not conditional (less or more than) operators.

Based on:

.NET 4.5

C# program that adds elements to List

using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<int> list = new List<int>();
	list.Add(2);
	list.Add(3);
	list.Add(5);
	list.Add(7);
    }
}
Int

A note. The above example adds a primitive type (int) to a List collection. But a List can also hold reference types and object instances. Non-int types work just as well.

Add
Steps

AddRange. For adding many elements at once—adding an array to a List—we use the AddRange method. This can simplify code that combines collections.

AddRange
For loop

Loops. We loop through a List with the for and foreach-loops. The syntax is like that for an array, except we use Count, not Length, for the upper bound.

Tip:You can loop backwards through your List. Start with list.Count - 1, and decrement to >= 0.

C# program that loops through List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<int> list = new List<int>();
	list.Add(2);
	list.Add(3);
	list.Add(7);

	foreach (int prime in list) // Loop through List with foreach.
	{
	    Console.WriteLine(prime);
	}

	for (int i = 0; i < list.Count; i++) // Loop with for.
	{
	    Console.WriteLine(list[i]);
	}
    }
}

Output: repeated twice

2
3
7
Pound symbol

Count, clear. To get the number of elements, access the Count property. This is fast—just avoid the Count extension method. Count, on the List type, is equal to Length on arrays.

Clear:Here we use the Clear method, along with the Count property, to erase all the elements in a List.

Info:Before Clear is called, this List has 3 elements. After Clear is called, it has 0 elements.

List Clear

Null:You can assign the List to null instead of calling Clear, with similar performance.

C# program that counts List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<bool> list = new List<bool>();
	list.Add(true);
	list.Add(false);
	list.Add(true);
	Console.WriteLine(list.Count); // 3

	list.Clear();
	Console.WriteLine(list.Count); // 0
    }
}

Output

3
0
Copy: new object copied

Copy array. Here we create a List with elements from an array. We use the List constructor and pass it the array. List receives this parameter and fills its values from it.

Caution:The array element type must match the List element type or compilation will fail.

C# program that copies array to List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	int[] arr = new int[3]; // New array with 3 elements
	arr[0] = 2;
	arr[1] = 3;
	arr[2] = 5;
	List<int> list = new List<int>(arr); // Copy to List
	Console.WriteLine(list.Count);       // 3 elements in List
    }
}

Output

3
Find icon

Find. We test each element for a certain value. This shows the foreach-loop, which tests to see if 3 is in the List of prime numbers. More advanced methods too are available.

Note:The Find method declaratively searches. We pass it a lambda expression. It can sometimes result in shorter code.

Find
C# program that uses foreach on List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	// New list for example
	List<int> primes = new List<int>(new int[] { 2, 3, 5 });

	// See if List contains 3
	foreach (int number in primes)
	{
	    if (number == 3) // Will match once
	    {
		Console.WriteLine("Contains 3");
	    }
	}
    }
}

Output

Contains 3
Cover logo

Contains, Exists, IndexOf. These methods all provide searching. They vary in arguments and return values. With Predicate methods, we influence what elements match.

ContainsExistsIndexOf

Note:Contains returns only a bool. Exists receives a Predicate and returns a bool. IndexOf returns the position of the element found.


Size

Capacity. We can use the Capacity property on List, or pass an integer to the constructor (which sets an initial capacity) to improve allocation performance.

Capacity

Note:Setting a capacity sometimes improves performance by nearly two times for adding elements.

However:Adding elements, and resizing List, is not usually a performance bottleneck in programs that access data.


Trim string

TrimExcess. This method's usage is limited. It reduces the memory used by lists with large capacities. And as MSDN states, TrimExcess often does nothing.

Note:It is unclear how TrimExcess feels about its status. I wouldn't want to upset its feelings.

The TrimExcess method does nothing if the list is at more than 90 percent of capacity.

TrimExcess: MSDN
Question

BinarySearch. This implements (fittingly) the binary search algorithm. Binary search uses guesses to find the correct element faster than linear searching.

BinarySearch
Foreach loop construct

ForEach. This is a method. Sometimes you may not want to write a regular foreach loop, which makes ForEach useful. It accepts an Action.

Warning:Be cautious when you use Predicates and Actions. These objects can decrease the readability of code.


All extension method

TrueForAll. This method accepts a Predicate. If the Predicate returns true for each element in the List, the TrueForAll method will also return true.

Info:It checks the entire list—unless an element doesn't match and it returns false early.


Join objects together

Join string list. Next, we use string.Join on a List of strings. This is helpful when you need to turn several strings into one comma-delimited string.

ToArray:It requires the ToArray instance method on List. This ToArray is not an extension method.

Tip:The biggest advantage of Join here is that no trailing comma is present on the resulting string.

C# program that joins List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	// List of cities we need to join
	List<string> cities = new List<string>();
	cities.Add("New York");
	cities.Add("Mumbai");
	cities.Add("Berlin");
	cities.Add("Istanbul");

	// Join strings into one CSV line
	string line = string.Join(",", cities.ToArray());
	Console.WriteLine(line);
    }
}

Output

New York,Mumbai,Berlin,Istanbul
Dictionary optimizes lookups with hash codes

Keys in Dictionary. We use the List constructor to get a List of keys from a Dictionary. This is a simple way to iterate over Dictionary keys or store them elsewhere.

Keys:The Keys property returns an enumerable collection of keys. But a List of these elements is more usable.

C# that converts Keys

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	// Populate example Dictionary
	var dict = new Dictionary<int, bool>();
	dict.Add(3, true);
	dict.Add(5, false);

	// Get a List of all the Keys
	List<int> keys = new List<int>(dict.Keys);
	foreach (int key in keys)
	{
	    Console.WriteLine(key);
	}
    }
}

Output

3, 5
Insert: placing an element into a collection

Insert. This is a useful but slow method. The string here is inserted into index 1. This makes it the second element. If you Insert often, consider Queue and LinkedList.

Insert

Also:A Queue may allow simpler usage of the collection in your code. Your intent may be clearer.

Queue
C# that inserts into List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<string> dogs = new List<string>(); // Example List

	dogs.Add("spaniel");         // Contains: spaniel
	dogs.Add("beagle");          // Contains: spaniel, beagle
	dogs.Insert(1, "dalmatian"); // spaniel, dalmatian, beagle

	foreach (string dog in dogs) // Display for verification
	{
	    Console.WriteLine(dog);
	}
    }
}

Output

spaniel
dalmatian
beagle
Range

InsertRange. This method inserts many elements at once. Please be aware that these can impact performance in a negative way—successive elements must be copied.

InsertRange
Method call

Remove. We present examples for Remove,
RemoveAt,
RemoveAll
and RemoveRange. In general Remove operates the same way as Insert. It too hinders performance.

RemoveRemoveAtRemoveAll
Sort: ordering elements from A to Z, alphabetically

Sort orders the elements in the List. For strings it orders alphabetically. For integers or other numbers it orders from lowest to highest.

Sort

Note:Sort acts upon elements depending on type. It is possible to provide a custom method.


Reverse

Reverse. With this method no sorting occurs—the original order is intact but inverted. The strings contained in the List are left unchanged.

Array.Reverse

Internally:This method invokes the Array.Reverse method. Many list methods are implemented with Array methods.

C# that uses Reverse

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<string> list = new List<string>();
	list.Add("anchovy");
	list.Add("barracuda");
	list.Add("bass");
	list.Add("viperfish");

	// Reverse List in-place, no new variables required.
	list.Reverse();

	foreach (string value in list)
	{
	    Console.WriteLine(value);
	}
    }
}

Output

viperfish
bass
barracuda
anchovy
Convert

Conversion of data types is a challenge. You can convert your List to an array of the same type using the instance method ToArray. There are examples of these conversions.

List to ArrayCopyTo

Strings:Some string methods can be used with the List type. We use, with List, the Concat and Join methods.

string.ConcatJoin

GetRange. This returns a range of elements in a List. This is similar to the Take and Skip methods from LINQ. It has different syntax. The result List can be used like any other List.

LINQ
C# that gets ranges from List

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<string> rivers = new List<string>(new string[]
	{
	    "nile",
	    "amazon",     // River 2
	    "yangtze",    // River 3
	    "mississippi",
	    "yellow"
	});

	// Get rivers 2 through 3
	List<string> range = rivers.GetRange(1, 2);
	foreach (string river in range)
	{
	    Console.WriteLine(river);
	}
    }
}

Output

amazon
yangtze
DataTable

DataGridView. We can use the List type with a DataGridView. But sometimes it is better to convert the List to a DataTable. For a List of string arrays, this will work better.

Convert List, DataTable
Not equal

Equality. Sometimes we need to test two Lists for equality, even when their elements are unordered. We can sort and then compare, or use a custom List equality method.

Note:This site contains an example of a method that tests lists for equality in an unordered way. A set collection might be better.

List Element Equality
Structure

Structs. When using List, we can improve performance and reduce memory usage with structs instead of classes. A List of structs is allocated in contiguous memory, unlike a List of classes.

However:Using structs will actually decrease performance when they are used as parameters in methods such as those on the List type.

Structs
Var keyword

Var keyword. This shorten your lines of code, which sometimes improves readability. The var keyword has no effect on performance, only readability for programmers.

Var
C# that uses var with List

using System.Collections.Generic;

class Program
{
    static void Main()
    {
	var list1 = new List<int>();       // <- var keyword used
	List<int> list2 = new List<int>(); // <- Is equivalent to
    }
}
Arrow indicates looping

GetEnumerator. Programs are built upon many abstractions. With List even loops can be abstracted into an Enumerator. We can use the same methods to loop over a List or an array.

GetEnumerator
Constructor: create new

Initialize. Many syntax forms can initialize a List. Most of them have equivalent performance. In fact most are compiled to the same intermediate language instructions.

Initialize List

Programs are complex. They have many contexts, many paths. We use List with methods from System.Linq and System.IO. We manipulate it and serialize it.

List ConcatRemove DuplicatesSerialize List

Types:We test integer Lists, string Lists, static Lists, nested Lists and null Lists. They are used in similar ways.

Nested ListNull ListStatic List
C# programming language

List is a constructed, parametric type. It is powerful and performs well. It provides flexible allocation and growth, making it easier to use than arrays.


List's syntax is at first confusing. But you become used to it. In most programs lacking strict memory or performance constraints, List is ideal.

C#