TheDeveloperBlog.com

Home | Contact Us

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

<< Back to C-SHARP

C# List Examples

Create a new List and add elements to it. Loop over its elements with for and foreach.
List. As millions of years pass, layers of rock are added to the ground. The fossil record is a list. In a program, we could use a List collection to represent this.
List details. The List is initialized with the new keyword. When we call Add, the List adjusts its size as needed. It is used in nearly all larger C# programs.Initialize List
First example. Here we create 2 separate lists of ints. We add 4 prime numbers to each List. The values are stored in the order added—2, 3, 5 and then 7.

Version 1: We call Add() 4 times with the number as the argument. The end count of the list is 4.

Add

Version 2: This code adds all 4 numbers in a single expression—it is easier to read, and the code generated is the same.

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

C# program that uses List, Add, initializer using System; using System.Collections.Generic; class Program { static void Main() { // Version 1: create a List of ints. // ... Add 4 ints to it. var numbers = new List<int>(); numbers.Add(2); numbers.Add(3); numbers.Add(5); numbers.Add(7); Console.WriteLine("LIST 1: " + numbers.Count); // Version 2: create a List with an initializer. var numbers2 = new List<int>() { 2, 3, 5, 7 }; Console.WriteLine("LIST 2: " + numbers2.Count); } } Output LIST 1: 4 LIST 2: 4
Foreach-loop. This is the clearest loop when no index is needed. It automatically sets each element to a name we specify—here we use the identifier "prime."

Part A: We use the "foreach" keyword and declare a variable that is assigned to each element as we pass over it.

Part B: In the foreach-loop, we access the "prime" variable, which is the current element. We print each int to the screen.

C# program that uses foreach, List using System.Collections.Generic; class Program { static void Main() { List<int> list = new List<int>() { 2, 3, 7 }; // Part A: loop through List with foreach. foreach (int prime in list) { // Part B: access each element with name. System.Console.WriteLine("PRIME ELEMENT: {0}", prime); } } } Output PRIME ELEMENT: 2 PRIME ELEMENT: 3 PRIME ELEMENT: 7
For-loop. Sometimes we want to access indexes of a List as we loop over its elements. With the index, we can test other collections, or perform validations. A for-loop is ideal here.

Part A: Here we use a for-loop. We begin at zero. We end at Count: the Count property returns the number of elements in the List.

Part B: We print each element index with Console.WriteLine. We use a string interpolation expression to format the string.

C# program that uses for, List using System; using System.Collections.Generic; class Program { static void Main() { List<int> list = new List<int>(new int[]{ 2, 3, 7 }); // Part A: loop with for and access count. for (int i = 0; i < list.Count; i++) { // Part B: access element with index. Console.WriteLine($"{i} = {list[i]}"); } } } Output 0 = 2 1 = 3 2 = 7
For-loop, reverse. Much like an array, we can access the elements in a List in any way we like. We can loop over the List elements in reverse with a for-loop.

Start: For a reverse loop, we must access the last element first, so we get the Count and subtract one from it. This is the last index.

C# program that uses for reverse, List using System; using System.Collections.Generic; class Program { static void Main() { var votes = new List<bool> { false, false, true }; // Loop through votes in reverse order. for (int i = votes.Count - 1; i >= 0; i--) { Console.WriteLine("DECREMENT LIST LOOP: {0}", votes[i]); } } } Output DECREMENT LIST LOOP: True DECREMENT LIST LOOP: False DECREMENT LIST LOOP: False
AddRange, InsertRange. For adding many elements at once, we use the InsertRange and AddRange methods. InsertRange can insert at an index, while AddRange adds at the end.AddRange, InsertRange

Argument 1: The first argument to InsertRange here is the position (index) where we want to insert new elements in the List.

Argument 2: The second argument to InsertRange is an IEnumerable—here, a string array. These strings are inserted at the index specified.

Result: We create a List of 2 strings, then add 2 strings from an array to index 1. The result List has 4 strings.

C# program that uses AddRange using System; using System.Collections.Generic; class Program { static void Main() { // Create a list of 2 strings. var animals = new List<string>() { "bird", "dog" }; // Insert strings from an array in position 1. animals.InsertRange(1, new string[] { "frog", "snake" }); foreach (string value in animals) { Console.WriteLine("RESULT: " + value); } } } Output RESULT: bird RESULT: frog RESULT: snake RESULT: dog
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() { // Create new array with 3 elements. int[] array = new int[] { 2, 3, 5 }; // Copy the array to a List. List<int> copied = new List<int>(array); // Print size of List. Console.WriteLine("COPIED COUNT: {0}", copied.Count); } } Output COPIED COUNT: 3
List parameter. Lists do not exist just to be allocated and looped over. We want to test and examine elements to solve real-world problems in our programs.

Main: Here we pass a List to ContainsValue300. The List can be passed as an argument—only the reference, not all elements, are copied.

ContainsValue300: This method uses a foreach-loop, which tests to see if 300 is in a list of numbers.

If

Result: The values List contains the value 300, so our custom method returns the boolean true.

C# program that uses foreach using System; using System.Collections.Generic; class Program { static void Main() { var values = new List<int>() { 200, 300, 500 }; // Pass list the method. if (ContainsValue300(values)) { Console.WriteLine("RETURNED TRUE"); } } static bool ContainsValue300(List<int> list) { foreach (int number in list) { // See if the element in the list equals 300. if (number == 300) { return true; } } // No return was reached, so nothing matched. return false; } } Output RETURNED TRUE
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
ForEach. This is a method. Sometimes we may not want to write a traditional foreach-loop. Here ForEach is useful. It accepts an Action.

Example: We have a 2-element string List. Then we call ForEach with a lambda that writes each element "a" to the console.

C# program that uses ForEach on List using System; using System.Collections.Generic; class Program { static void Main() { var animals = new List<string>() { "bird", "dog" }; // Use ForEach with a lambda action. // ... Write each string to the console. animals.ForEach(a => Console.WriteLine("ANIMAL: " + a)); } } Output ANIMAL: bird ANIMAL: dog
TrueForAll. This method accepts a Predicate. If the Predicate returns true for each element in the List, TrueForAll() will also return true.

And: TrueForAll() checks the entire list—unless an element doesn't match (it has an early exit condition).

C# program that uses TrueForAll on List using System; using System.Collections.Generic; class Program { static void Main() { var numbers = new List<int> { 10, 11, 12 }; // Call TrueForAll to ensure a condition is true. if (numbers.TrueForAll(element => element < 20)) { Console.WriteLine("All elements less than 20"); } } } Output All elements less than 20
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# 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
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# program 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# program 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
Remove. With this method we eliminate the first matching element in the List. If we pass the value 20 to Remove, the first element in the list with value 20 is removed.

Info: We can call Remove with an argument that does not occur in the list. This will not cause an exception.

List Remove

RemoveAll: We can remove more than 1 element at once with the RemoveAll method.

RemoveAll
C# program that uses Remove using System; using System.Collections.Generic; class Program { static void Main() { var numbers = new List<int>() { 10, 20, 30 }; // Remove this element by value. numbers.Remove(20); foreach (int number in numbers) { Console.WriteLine("NOT REMOVED: {0}", number); } // This has no effect. numbers.Remove(2000); } } Output NOT REMOVED: 10 NOT REMOVED: 30
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# program 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
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# program 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
SequenceEqual. This is a method from System.Linq. It tells us whether 2 collections (IEnumerables) have the same exact elements. The number of elements and order must be the same.

Tip: We can use SequenceEqual on Lists, arrays, or other collections. It is not optimally fast, but it can reduce code size.

SequenceEqual
C# program that uses SequenceEqual using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { var numbers = new List<int> { 10, 20, 30 }; var numbers2 = new List<int> { 10, 20, 30 }; // See if the two lists are equal. if (numbers.SequenceEqual(numbers2)) { Console.WriteLine("LISTS ARE EQUAL"); } } } Output LISTS ARE EQUAL
Var keyword. This shortens lines of code, which sometimes improves readability. Var has no effect on performance, only readability for programmers.Var
C# program 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>(); // This is equivalent. } }
Benchmark, create List. Suppose we want to create a List of 3 elements with an initializer. If we can use an array instead, the program will be faster.

Version 1: We create a string array of 3 elements with an array initializer. We test its length.

Initialize Array

Version 2: This code creates a List of strings with an initializer. The List is an additional object—performance is affected.

Result: It is faster to allocate an array of strings. For some programs, this could help improve performance.

C# program that tests List creation time using System; using System.Collections.Generic; using System.Diagnostics; class Program { const int _max = 1000000; static void Main() { // Version 1: create string array with 3 elements in it. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { var items = new string[] { "bird", "frog", "fish" }; if (items.Length == 0) { return; } } s1.Stop(); // Version 2: create string list with 3 elements in it. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { var items = new List<string>() { "bird", "frog", "fish" }; if (items.Count == 0) { return; } } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); } } Output 14.03 ns Create string array 40.79 ns Create string List
Contains, Find and Exist. These methods all provide searching. They vary in arguments accepted. With Predicates, we influence what elements match.List ContainsList Find, Exists
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.

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

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

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

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

List.TrimExcess: Microsoft Docs
BinarySearch. This implements (fittingly) the binary search algorithm. Binary search uses guesses to find the correct element faster than linear searching.BinarySearch
Conversion. 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

List to string: Some string methods are used with lists. We use Concat and Join. Sometimes StringBuilder is also useful.

Convert List, StringConcatJoin: string.Join

DataTable: Sometimes it is better to convert a 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.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
GetEnumerator. Programs are built upon many abstractions. With List, even loops can be abstracted (into an Enumerator). We use the same methods to loop over a List or an array.GetEnumerator
Combine lists. With Concat, a method from the System.Linq namespace, we can add one list to another. Only a single method call is required.Concat, List
Remove duplicates. With Distinct() we can remove duplicates from a List. Other algorithms, that use Dictionary, can be used to scan for and erase duplicates.Dedupe List
Serialize list. A List can be read from, and written to, a file. This is list serialization. The "Serializable" attribute is useful here.Serialize List
Notes, List. This generic (like all others) is created with a type parameter. List is powerful: it provides flexible allocation and growth. Lists can be nested, static, or assigned to null.Nested ListNull ListStatic List
A summary. 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.
© TheDeveloperBlog.com
The Dev Codes

Related Links:


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