C# | Arrays
Declaring an array
Section titled “Declaring an array”An array can be declared and filled with the default value using square bracket ([]) initialization syntax. For example, creating an array of 10 integers:
int[] arr = new int[10];Indices in C# are zero-based. The indices of the array above will be 0-9. For example:
int[] arr = new int[3] {7,9,4};Console.WriteLine(arr[0]); //outputs 7Console.WriteLine(arr[1]); //outputs 9Which means the system starts counting the element index from 0. Moreover, accesses to elements of arrays are done in constant time. That means accessing to the first element of the array has the same cost (in time) of accessing the second element, the third element and so on.
You may also declare a bare reference to an array without instantiating an array.
int[] arr = null; // OK, declares a null reference to an array.int first = arr[0]; // Throws System.NullReferenceException because there is no actual array.An array can also be created and initialized with custom values using collection initialization syntax:
int[] arr = new int[] { 24, 2, 13, 47, 45 };The new int[] portion can be omitted when declaring an array variable. This is not a self-contained expression, so using it as part of a different call does not work (for that, use the version with new):
int[] arr = { 24, 2, 13, 47, 45 }; // OKint[] arr1;arr1 = { 24, 2, 13, 47, 45 }; // Won't compileImplicitly typed arrays
Alternatively, in combination with the var keyword, the specific type may be omitted so that the type of the array is inferred:
// same as int[]var arr = new [] { 1, 2, 3 };// same as string[]var arr = new [] { "one", "two", "three" };// same as double[]var arr = new [] { 1.0, 2.0, 3.0 };Initializing an array filled with a repeated non-default value
Section titled “Initializing an array filled with a repeated non-default value”As we know we can declare an array with default values:
int[] arr = new int[10];This will create an array of 10 integers with each element of the array having value 0 (the default value of type int).
To create an array initialized with a non-default value, we can use Enumerable.Repeat from the System.Linq Namespace:
bool[] booleanArray = Enumerable.Repeat(true, 10).ToArray();int[] intArray = Enumerable.Repeat(100, 5).ToArray();string[] strArray = Enumerable.Repeat("C#", 5).ToArray();Copying arrays
Section titled “Copying arrays”Copying a partial array with the static Array.Copy() method, beginning at index 0 in both, source and destination:
var sourceArray = new int[] { 11, 12, 3, 5, 2, 9, 28, 17 };var destinationArray= new int[3];Array.Copy(sourceArray, destinationArray, 3);
// destinationArray will have 11,12 and 3Copying the whole array with the CopyTo() instance method, beginning at index 0 of the source and the specified index in the destination:
var sourceArray = new int[] { 11, 12, 7 };var destinationArray = new int[6];sourceArray.CopyTo(destinationArray, 2);
// destinationArray will have 0, 0, 11, 12, 7 and 0Clone is used to create a copy of an array object.
var sourceArray = new int[] { 11, 12, 7 };var destinationArray = (int)sourceArray.Clone();
//destinationArray will be created and will have 11,12,17.Both CopyTo and Clone perform shallow copy which means the contents contains references to the same object as the elements in the original array.
Comparing arrays for equality
Section titled “Comparing arrays for equality”LINQ provides a built-in function for checking the equality of two IEnumerables, and that function can be used on arrays.
The SequenceEqual function will return true if the arrays have the same length and the values in corresponding indices are equal, and false otherwise.
int[] arr1 = { 3, 5, 7 };int[] arr2 = { 3, 5, 7 };bool result = arr1.SequenceEqual(arr2);Console.WriteLine("Arrays equal? {0}", result);This will print:
Arrays equal? TrueMulti-dimensional arrays
Section titled “Multi-dimensional arrays”Arrays can have more than one dimension. The following example creates a two-dimensional array of ten rows and ten columns:
int[,] arr = new int[10, 10];An array of three dimensions:
int[,,] arr = new int[10, 10, 10];You can also initialize the array upon declaration:
int[,] arr = new int[4, 2] { {1, 1}, {2, 2}, {3, 3}, {4, 4} };
// Access a member of the multi-dimensional array:Console.Out.WriteLine(arr[3, 1]); // 4Getting and setting array values
Section titled “Getting and setting array values”int[] arr = new int[] { 0, 10, 20, 30};
// GetConsole.WriteLine(arr[2]); // 20
// Setarr[2] = 100;
// Get the updated valueConsole.WriteLine(arr[2]); // 100Iterate over an array
Section titled “Iterate over an array”int[] arr = new int[] {1, 6, 3, 3, 9};
for (int i = 0; i < arr.Length; i++){ Console.WriteLine(arr[i]);}using foreach:
foreach (int element in arr){ Console.WriteLine(element);}using unsafe access with pointers https://msdn.microsoft.com/en-ca/library/y31yhkeb.aspx
unsafe{ int length = arr.Length; fixed (int* p = arr) { int* pInt = p; while (length-- > 0) { Console.WriteLine(*pInt); pInt++;// move pointer to next element } }}Output:
1
6
3
3
9
Jagged arrays
Section titled “Jagged arrays”Jagged arrays are arrays that instead of primitive types, contain arrays (or other collections). It’s like an array of arrays - each array element contains another array.
They are similar to multidimensional arrays, but have a slight difference - as multidimensional arrays are limited to a fixed number of rows and columns, with jagged arrays, every row can have a different number of columns.
Declaring a jagged array
For example, declaring a jagged array with 8 columns:
int[][] a = new int[8][];The second [] is initialized without a number. To initialize the sub arrays, you would need to do that separately:
for (int i = 0; i < a.length; i++){ a[i] = new int[10];}Getting/Setting values
Now, getting one of the subarrays is easy. Let’s print all the numbers of the 3rd column of a:
for (int i = 0; i < a[2].length; i++){ Console.WriteLine(a[2][i]);}Getting a specific value:
a[<row_number>][<column_number>]Setting a specific value:
a[<row_number>][<column_number>] = <value>Remember: It’s always recommended to use jagged arrays (arrays of arrays) rather than multidimensional arrays (matrixes). It’s faster and safer to use.
Note on the order of the brackets
Consider a three-dimensional array of five-dimensional arrays of one-dimensional arrays of int. This is written in C# as:
int[,,][,,,,][] arr = new int[8, 10, 12][,,,,][];In the CLR type system, the convention for the ordering of the brackets is reversed, so with the above arr instance we have:
arr.GetType().ToString() == "System.Int32[][,,,,][,,]"and likewise:
typeof(int[,,][,,,,][]).ToString() == "System.Int32[][,,,,][,,]"Creating an array of sequential numbers
Section titled “Creating an array of sequential numbers”LINQ provides a method that makes it easy to create a collection filled with sequential numbers. For example, you can declare an array which contains the integers between 1 and 100.
The Enumerable.Range method allows us to create sequence of integer numbers from a specified start position and a number of elements.
The method takes two arguments: the starting value and the number of elements to generate.
Enumerable.Range(int start, int count)Note that count cannot be negative.
Usage:
Section titled “Usage:”int[] sequence = Enumerable.Range(1, 100).ToArray();This will generate an array containing the numbers 1 through 100 ([1, 2, 3, ..., 98, 99, 100]).
Because the Range method returns an IEnumerable<int>, we can use other LINQ methods on it:
int[] squares = Enumerable.Range(2, 10).Select(x => x * x).ToArray();This will generate an array that contains 10 integer squares starting at 4: [4, 9, 16, ..., 100, 121].
Array covariance
Section titled “Array covariance”string[] strings = new[] {"foo", "bar"};object[] objects = strings; // implicit conversion from string[] to object[]This conversion is not type-safe. The following code will raise a runtime exception:
string[] strings = new[] {"Foo"};object[] objects = strings;
objects[0] = new object(); // runtime exception, object is not stringstring str = strings[0]; // would have been bad if above assignment had succeededChecking if one array contains another array
Section titled “Checking if one array contains another array”public static class ArrayHelpers{ public static bool Contains<T>(this T[] array, T[] candidate) { if (IsEmptyLocate(array, candidate)) return false;
if (candidate.Length > array.Length) return false;
for (int a = 0; a <= array.Length - candidate.Length; a++) { if (array[a].Equals(candidate[0])) { int i = 0; for (; i < candidate.Length; i++) { if (false == array[a + i].Equals(candidate[i])) break; } if (i == candidate.Length) return true; } } return false; }
static bool IsEmptyLocate<T>(T[] array, T[] candidate) { return array == null || candidate == null || array.Length == 0 || candidate.Length == 0 || candidate.Length > array.Length; }}/// Sample
byte[] EndOfStream = Encoding.ASCII.GetBytes("---3141592---");byte[] FakeReceivedFromStream = Encoding.ASCII.GetBytes("Hello, world!!!---3141592---");if (FakeReceivedFromStream.Contains(EndOfStream)){ Console.WriteLine("Message received");}Arrays as IEnumerable<> instances
Section titled “Arrays as IEnumerable<> instances”All arrays implement the non-generic IList interface (and hence non-generic ICollection and IEnumerable base interfaces).
More importantly, one-dimensional arrays implement the IList<> and IReadOnlyList<> generic interfaces (and their base interfaces) for the type of data that they contain. This means that they can be treated as generic enumerable types and passed in to a variety of methods without needing to first convert them to a non-array form.
int[] arr1 = { 3, 5, 7 };IEnumerable<int> enumerableIntegers = arr1; //Allowed because arrays implement IEnumerable<T>List<int> listOfIntegers = new List<int>();listOfIntegers.AddRange(arr1); //You can pass in a reference to an array to populate a List.After running this code, the list listOfIntegers will contain a List<int> containing the values 3, 5, and 7.
The IEnumerable<> support means arrays can be queried with LINQ, for example arr1.Select(i => 10 * i).
Syntax
Section titled “Syntax”Remarks
Section titled “Remarks”In C#, an array is a reference type, which means it is nullable.
An array has a fixed length, which means you cant .Add() to it or .Remove() from it. In order to use these, you would need a dynamic array - List or ArrayList.