TheDeveloperBlog.com

Home | Contact Us

C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML

C# List Examples

This C# tutorial covers the List collection. A List is a dynamic array that grows as needed.

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.

Dynamic in size, with many methods, List makes life easier. List is a generic type. We need to use < and > in the List declaration. It is a newer, faster ArrayList.

ArrayList

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);
    }
}

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

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

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: We can loop backwards through a 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

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.

Clear

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

Null: We 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 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

Test elements. We test each element for a certain value. This example shows a foreach-loop, which tests to see if 3 is in a list of primes.

C# program that uses foreach

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

IndexOf. This determines the element index of a certain value in the List collection. It searches for the first position (from the start) of the value.

Note: IndexOf has two overloads. It works in the same way as string's IndexOf. It searches by value and returns the location.

C# program that uses IndexOf

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
	List<int> primes = new List<int>(new int[] { 19, 23, 29 });

	int index = primes.IndexOf(23); // Exists.
	Console.WriteLine(index);

	index = primes.IndexOf(10); // Does not exist.
	Console.WriteLine(index);
    }
}

Output

1
-1

Contains, Exists, Find. These methods all provide searching. They vary in arguments accepted. With Predicates, we influence what elements match.

ContainsExistsFind

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.

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

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

BinarySearch

ForEach. This is a method. Sometimes we may not want to write a traditional foreach-loop. Here ForEach is useful. It accepts an Action.

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

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

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

Join string list. Next we use string.Join on a List of strings. This is helpful when we 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# 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

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. This is a useful but slow method. The string here is inserted at 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 our code. This may be easier to understand.

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

InsertRange. This method inserts many elements at once. Please be aware it can impact performance in a negative way. Successive elements must be copied.

InsertRange

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 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. 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

Conversion of data types is a challenge. We can convert a 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 class. 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

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

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: A method can test for equality in an unordered way. But a set collection might be better.

List Element Equality

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. This shortens lines of code, which sometimes improves readability. Var 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
    }
}

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

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

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 we become used to it. In most programs lacking strict memory or performance constraints, List is ideal.


Related Links

Adjectives Ado Ai Android Angular Antonyms Apache Articles Asp Autocad Automata Aws Azure Basic Binary Bitcoin Blockchain C Cassandra Change Coa Computer Control Cpp Create Creating C-Sharp Cyber Daa Data Dbms Deletion Devops Difference Discrete Es6 Ethical Examples Features Firebase Flutter Fs Git Go Hbase History Hive Hiveql How Html Idioms Insertion Installing Ios Java Joomla Js Kafka Kali Laravel Logical Machine Matlab Matrix Mongodb Mysql One Opencv Oracle Ordering Os Pandas Php Pig Pl Postgresql Powershell Prepositions Program Python React Ruby Scala Selecting Selenium Sentence Seo Sharepoint Software Spellings Spotting Spring Sql Sqlite Sqoop Svn Swift Synonyms Talend Testng Types Uml Unity Vbnet Verbal Webdriver What Wpf