C# Array Examples, String Arrays

Create and loop over a string array. Access array Length and get elements at indexes.
Array. The tiger hunts at night. It searches for its next kill. Its main targets include an array of animals: deer, moose, boars. A string array could represent these animals.
In programs, arrays are inside many things. An array has an element type. Its elements are accessed with an index. An array cannot be resized—it can only be created (and then replaced).Initialize Array
String arrays. We begin with string arrays. Square brackets are used for all arrays. The syntax is simple and easy to remember (with practice).

Version 1: This code creates a string array of 3 elements, and then assign strings to the array indexes (starting at 0).

Version 2: This string array is created with an array initializer expression. It is shorter and easier to type.

Version 3: Here we do not even declare the type of the array. The 3 versions are compiled to the same instructions.

C# program that uses string arrays, initializers using System; class Program { static void Main() { // Version 1: create empty string array. // ... Assign into the array. string[] animals = new string[3]; animals[0] = "deer"; animals[1] = "moose"; animals[2] = "boars"; Console.WriteLine("ARRAY 1: " + animals.Length); // Version 2: use array initializer. string[] animals2 = new string[] { "deer", "moose", "boars" }; Console.WriteLine("ARRAY 2: " + animals2.Length); // Version 3: a shorter array initializer. string[] animals3 = { "deer", "moose", "boars" }; Console.WriteLine("ARRAY 3: " + animals3.Length); } } Output ARRAY 1: 3 ARRAY 2: 3 ARRAY 3: 3
Int array, parameter. In structural programming we pass arrays as arguments to methods. The entire contents of the array are not copied—just the small reference.

MultiplyFirstElement: This receives a reference to the int array. It accesses the array and returns a value based on the first element.

Result: We print the first element multiplied by 2 to the screen. The array exists in only one place in the managed heap.

Tip: We can think of an array as a class with a variable number of fields, each accessed with an index.

C# program that receives array parameter using System; class Program { static void Main() { // Create 3-element array. int[] array = { -5, -6, -7 }; // Pass array reference to method. int result = MultiplyFirstElement(array); Console.WriteLine("FIRST ELEMENT MULTIPLIED: {0}", result); } static int MultiplyFirstElement(int[] array) { // Multiply the first element by 2 and return it. return array[0] * 2; } } Output -10
Return. We can return arrays from methods. A method might need to generate data for the array beforehand. Even random data could be returned this way.

GetTreeNameArray: This method creates an array of 3 strings. More strings could be added. Any array initializer could be used.

Result: The GetTreeNameArray() method is called, then joined into a string with string.Join. Then we write it to the screen.

C# program that returns array reference using System; class Program { static void Main() { // Get tree array, and merge its results into a single string. string result = string.Join("; ", GetTreeNameArray()); // Write the tree names. Console.WriteLine("TREES: {0}", result); } static string[] GetTreeNameArray() { // Put 3 tree names in the array and return it. string[] array = { "Elm", "Oak", "Palm" }; return array; } } Output TREES: Elm; Oak; Palm
First. How can we get the first element? The first element is at index 0. It can be accessed by using the indexer syntax. To be safe, we often must check for empty arrays.

Test: This method receives an int array. It tests the array to be sure it is not null, and that the length is greater than 0.


Then: Test() will print the first element in the array to the console. This never causes an exception, because the array was tested first.

C# program that gets first array element using System; class Program { static void Main() { int[] array = new int[2]; // Create an array. array[0] = 10; array[1] = 3021; Test(array); Test(null); // No output. Test(new int[0]); // No output. } static void Test(int[] array) { if (array != null && array.Length > 0) { int first = array[0]; Console.WriteLine(first); } } } Output 10
Last. The last element's offset is equal to the array Length minus one. The Length property is always kept up-to-date by the runtime. But Length can equal 0 (in an empty array).

So: Often we need to check against null, and that the Length is greater than zero, before accessing the last element.

Tiger: The last string element is "tiger." The length is 4, and the last index is 3—we adjust the length to get the last index.

C# program that gets last array element using System; class Program { static void Main() { string[] animals = { "cat", "dog", "panther", "tiger" }; // Get the last string element. string last = animals[animals.Length - 1]; Console.WriteLine("LAST ELEMENT: {0}", last); } } Output tiger
Foreach-loop. With this loop, no indexes are needed—the loop itself handles the indexes. This makes some code simpler. We use string interpolation to display the colors.

Tip: For many programs, a foreach-loop is the clearest loop. If the logic does complicated things with indexes, use for.

C# program that uses foreach, array class Program { static void Main() { string[] array = { "red", "blue", "green" }; // Loop with foreach and write colors with string interpolation. foreach (string color in array) { System.Console.WriteLine($"Color = {color}"); } } } Output Color = red Color = blue Color = green
For-loop. With this loop we use indexes. We have a start, and end, and increment expression. We must then access the element from the array in an expression within the loop.

Here: We use a for-loop to iterate over a string array. The length of this array is 2, so the valid indexes are 0 and 1.

Info: The variable "i" is set to each array index. We can access multiple array elements if needed in a for-loop.

C# program that uses for, array using System; class Program { static void Main() { string[] array = new string[2]; array[0] = "Socrates"; array[1] = "Plato"; // Use for-loop on array. for (int i = 0; i < array.Length; i++) { // Get element, and print index and element value. string element = array[i]; Console.WriteLine("INDEX: {0}, VALUE: {1}", i, element); } } } Output INDEX: 0, VALUE: Socrates INDEX: 1, VALUE: Plato
Empty. Here is another syntax example. To create an empty string array, we can use an empty initializer expression. Or we can specify a 0 length.
C# program that creates empty string arrays using System; class Program { static void Main() { // Create string array with no elements. var empty1 = new string[] { }; Console.WriteLine(empty1.Length == 0); // This syntax has the same result. var empty2 = new string[0]; Console.WriteLine(empty2.Length == 0); } } Output True True
IndexOf. The Array class has many helpful methods—consider IndexOf. We can use this method to search an array by value. Here we find the index of the string "dog."

Warning: IndexOf methods return -1 when no element is found. This value often must be checked in an if-statement.

C# program that uses Array.IndexOf using System; class Program { static void Main() { string[] array = { "cat", "dog", "bird", "fish" }; // The dog string is at index 1. int dogIndex = Array.IndexOf(array, "dog"); Console.WriteLine(dogIndex); // There is no monkey string in the array. // ... So IndexOf returns -1. int monkeyIndex = Array.IndexOf(array, "monkey"); Console.WriteLine(monkeyIndex); } } Output 1 -1
Class, indexer. We use arrays as fields (or properties) in classes. This is useful for storing values. In the Test class here, we have a string array field.

Elements: The second part of the Test class is a property accessor. It provides a clean way for external code to access the internal array.

Indexer: The final part of the Test class is called an Indexer. An indexer uses the this-keyword.


Note: The indexer shown receives one parameter, an integer, and returns a value based on it.

C# program that uses string array in class class Program { static void Main() { // Create new instance with string array. Test test = new Test(); // Loop over elements with property. foreach (string element in test.Elements) { System.Console.WriteLine(element); } // Get first string element. System.Console.WriteLine(test[0]); } } public class Test { /// <summary> /// String array field instance. /// </summary> string[] _elements = { "one", "two", "three" }; /// <summary> /// String array property getter. /// </summary> public string[] Elements { get { return _elements; } } /// <summary> /// String array indexer. /// </summary> public string this[int index] { get { return _elements[index]; } } } Output one two three one
Join, Split. The string.Join() method receives a string array and combines the strings into one. And Split() separates strings that are joined together with a delimiter char.

Join: This example uses the Join method to combine the three string literals within the "elements" array.


Split: Finally we invoke Split to change our joined string back into a string array. The two string arrays are separate in memory.

C# program that uses Join and Split using System; class Program { static void Main() { string[] elements = { "cat", "dog", "fish" }; Console.WriteLine(elements[0]); // ... Join strings into a single string. string joined = string.Join("|", elements); Console.WriteLine(joined); // ... Separate joined strings with Split. string[] separated = joined.Split('|'); Console.WriteLine(separated[0]); } } Output cat cat|dog|fish cat
String args. When a C# program is started, an optional string array is received from the operating system. This array, args, contains string arguments.Main args

Start: Try creating a shortcut in Windows to your C# executable. The args array is empty when no arguments are passed.

Here: I added the argument string "hello world" to the command in the Windows shortcut. The two strings are received into the args array.

C# program that uses args string array using System; class Program { static void Main(string[] args) { // ... Loop over arguments passed to this program. foreach (string value in args) { Console.WriteLine("Argument: {0}", value); } Console.ReadLine(); } } Output Argument: hello Argument: world
Return ref, array element. With the ref keyword, we can return a reference to an array element. Here we have an int array. FirstElement returns a ref to the element at index 0.

Then: We can assign the result of FirstElement to modify the array. The "codes" array is modified.

C# program that returns ref to array element class Program { static ref int FirstElement(int[] array) { // Return ref to first element in array. return ref array[0]; } static void Main() { int[] codes = { 10, 20, 30 }; // Change first element to a new value. FirstElement(codes) = 60; // Display modified array. for (int i = 0; i < codes.Length; i++) { System.Console.WriteLine(codes[i]); } } } Output 60 20 30
IEnumerable. Arrays implement the IEnumerable interface for us automatically. This allows us to use arrays with LINQ extension methods, or pass arrays to methods that receive IEnumerable.IEnumerableLINQ

Tip: IEnumerable is an important part of using the C# language—it makes developing programs much easier.

C# program that uses IEnumerable, array using System; using System.Collections.Generic; class Program { static void Display(IEnumerable<int> values) { // This method can be used with arrays or Lists. foreach (int value in values) { Console.WriteLine("IENUMERABLE: " + value); } } static void Main() { int[] ids = { 10400, 20800, 40100 }; // Pass the int array to the Display method, which accepts it as an IEnumerable. Display(ids); } } Output IENUMERABLE: 10400 IENUMERABLE: 20800 IENUMERABLE: 40100
Exceptions. We must only access elements in an array that are present in the array. The values can be anything, but the accesses must occur within the length of the array.Exception

Tip: To make array usage easier, you can add helper methods that prevent out-of-range accesses, but this will reduce performance.

C# program that shows IndexOutOfRangeException using System; class Program { static void Main() { int[] test = { 10, 20, 30 }; Console.WriteLine(test[4]); } } Output Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array. at Program.Main() in ...Program.cs:line 7
Performance, array caching. Creating an array has some cost—memory needs to be allocated, and it will need to be garbage-collected. We can optimize by caching arrays of the required sizes.

Version 1: This code reuses a static array of 0 elements each time, so less burden is placed on the runtime.

Version 2: Here we create a new 0-element array each time—the costs add up so this version is several times slower.

Note: We can cache arrays of any size, and then reassign the elements within them—this usually will speed up a program.

C# program that uses array caching using System; using System.Diagnostics; class Program { const int _max = 1000000; static void Main() { // Version 1: use an empty array cache to avoid creating more than 1 array. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { if (Method1().Length != 0) { return; } } s1.Stop(); // Version 2: use a new array on each method call. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { if (Method2().Length != 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")); } static int[] _emptyArrayCache = new int[0]; static int[] Method1() { return _emptyArrayCache; // Return the cached array. } static int[] Method2() { return new int[0]; // Return a new array. } } Output 1.00 ns Cached array 4.79 ns New array
2D array. The C# language offers two-dimensional and multidimensional arrays. We also loop over 2D arrays. We use them with enumerators.2D Array

3D array: If two dimensions are not enough, try a three-dimensional array. Even further dimensions can be added.

3D Array

Jagged array: This is an array of arrays. It can be faster, or slower, than a 2D array based on usage.

Jagged Arrays
Types. Arrays can be of any type. We can have (for example) bool, byte, int or char arrays. And all these arrays can also be used as static fields or properties. They can be null.Bool ArrayByte ArrayChar ArrayEnum ArrayInt ArrayObject Array
Types, null. An array is a reference type (like a string) so it can be null. An array property often benefits from special-casing. We avoid returning null.Array: NullArray: Property, Avoid Null
Types, random. We can use the Random NextBytes method to fill a byte array with random values. This does not require much custom code.Array: Random
Types, strings. String arrays are different from other arrays. Strings are the only data type we declare with quoted values. Strings can be null. We often must convert these arrays.Convert Array, String
Combine. Suppose two arrays exist. We can combine them. Suppose a 2D array is present. We can flatten it into a single array. An array can operated upon in nearly any way imaginable.CombineFlatten
Methods. The Array type has many methods. To find things we use Array.Find with a predicate argument—FindAll finds many elements at once. And we can use BinarySearch on a sorted array.AsReadOnlyBinarySearchClearConstrainedCopyConvertAllCopyCreateInstanceExistsFindForEachIndexOfResizeReverseSortTrueForAll
Properties. The most commonly used property on arrays is the Length property. With Length, we access a stored field, and no costly counting occurs. Length has no internal loops.LengthIsFixedSize, IsReadOnly
Counting elements. There are many ways to count array elements. The Count() extension method can be used to count elements, like the Length property.Count Elements
ArraySegment. When we use arrays, we often want to read or write into the elements with indexes. ArraySegment helps here. It is an abstraction for part of an array.ArraySegment
Buffer. This deals with bytes in large arrays. It is fast. The Buffer type acts upon bytes, not array elements. It is not helpful with object data.Buffer
Performance, review. For the fastest programs, use arrays where possible. But if an array is resized often, a List is faster. Copying an array is a slow operation.Optimization
IL instructions. C# programs are compiled into IL instructions. Consider a string array. To create the array reference, "newarr string" is emitted. To assign each element "stelem" is used.IL: newarr, stelem
Research. An array is a collection of elements, all of a specific type. And these elements are stored together in memory. Each element is accessed by an integer index.

Quote: An array is a fixed collection of same-type data that are stored contiguously and that are accessible by an index (Algorithms in C++ Third Edition).

Quote: Arrays are the simplest and most common type of structured data (Code Complete).

Array notes. Arrays are great and they offer unmatched performance for looping and allocation. But to make our programming adventures easier, a List is often a better choice.List
A summary. Arrays are memory regions that contain elements. They store string references, ints, bytes (or any type). Even if not used directly, they are a core part of all programs.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to
Dot Net Perls