Array 2020
To fill the items of an array using C# array initialization syntax, we need to specify each array item within the scope of curly brackets {}.
This syntax can be helpful when we are creating an array of a known size and want to quickly specify the initial values. Let's look at the following alternative array declaration:
// Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFirstCSharpCode { class Program { static void ArrayInitialization() { string[] stringArray = new string[] { "Ludwig", "van", "Beethoven" }; Console.WriteLine("stringArray has {0} elements", stringArray.Length); bool[] boolArray = { false, false, true }; Console.WriteLine("boolArray has {0} elements", boolArray.Length); int[] intArray = new int[5] { 1, 2, 3, 4, 5 }; Console.WriteLine("intArray has {0} elements", intArray.Length); Console.WriteLine(); } static void Main(string[] args) { ArrayInitialization(); Console.ReadLine(); } } }
Output is:
stringArray has 3 elements boolArray has 3 elements intArray has 5 elements
When we make use of the curly bracket syntax, we do not need to specify the size of the array as in the stringArray type, given that this will be inferred by the number of items within the scope of the {}. Also note that use of the new keyword is optional as shown when we construct the boolArray type in the example.
In the case of the intArray declaration, the numeric value specified represents the number of elements in the array, not the value of the upper bound. If there is a mismatch between the declared size and the number of initializers, we'll get a compile error:
int[] array = new int[2] {1, 2, 3, 4}; // error: mismatch
When we define an array, we specify the type of item that can be within the array variable. While this seems quite straightforward, there is one notable twist. System.Object is the ultimate base class to each and every type including fundamental data types in the .NET type system. If we were to define an array object, the subitems could be anything at all. Take a look at the following ArrayOfObjects() method:
// Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFirstCSharpCode { class Program { static void ArrayOfObjects() { object[] myObj = new object[4]; myObj[0] = 1; myObj[1] = false; myObj[2] = new DateTime(2010, 11, 25); myObj[3] = "Ludwig van Beethoven"; foreach (object o in myObj) { Console.WriteLine("Type: {0}, value: {1}", o.GetType(), o); } Console.WriteLine(); } static void Main(string[] args) { ArrayOfObjects(); Console.ReadLine(); } } }
Output from the run is:
Type: System.Int32, value: 1 Type: System.Boolean, value: False Type: System.DateTime, value: 11/25/2010 12:00:00 AM Type: System.String, value: Ludwig van Beethoven
In the example, as we are iterating over the contents of myObj, we print out the underlying type of each item using the GetType() method of System.Object as well as the value of the current item. Note that GetType() can be used to obtain the fully qualified name of the item.
C# also supports two varieties of multidimensional arrays. The first one is a rectangular array which is an array of multiple dimensions, where each row is of the same length. Let's look at the following example.
// Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFirstCSharpCode { class Program { static void RectangularArray() { int[,] myRectArr; myRectArr = new int[6,6]; for(int i = 0; i < 6; i ++) for(int j = 0; j < 6; j++) myRectArr[i, j] = i * j; for(int i = 0; i < 6; i ++) { for(int j = 0; j < 6; j++) Console.Write(myRectArr[i, j] + " "); Console.WriteLine(); Console.WriteLine(); } static void Main(string[] args) { RectangularArray(); Console.ReadLine(); } } }
Output is:
0 0 0 0 0 0 0 1 2 3 4 5 0 2 4 6 8 10 0 3 6 9 12 15 0 4 8 12 16 20 0 5 10 15 20 25
The other type of multidimensional array is a jagged array. Jagged arrays contain some number of inner arrays, each of which may have a unique upper limit:
// Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFirstCSharpCode { class Program { static void myJaggedArray() { int[][] myJaggedArr = new int[5][]; for (int i = 0; i < myJaggedArr.Length; i++) { myJaggedArr[i] = new int[i + 7]; } for(int i = 0; i < 5; i ++) { for(int j = 0; j < myJaggedArr[i].Length; j++) Console.Write(myJaggedArr[i][j] + " "); Console.WriteLine(); } Console.WriteLine(); } static void Main(string[] args) { myJaggedArray(); Console.ReadLine(); } } }
Output is:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Once we have created an array, we are free to pass it as a parameter and receive it as a return value. In the following example, PrintArray() method takes an incoming array of ints and prints each while the GetStringArray() method populates an array of strings it to the caller.
// Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFirstCSharpCode { class Program { static void PrintArray(int[] myIntArr) { for (int i = 0; i < myIntArr.Length; i++) { Console.WriteLine("myIntArr[{0}] = {1}", i, myIntArr[i]); } } static string[] GetStringArray() { string[] strs = {"imperative", "declarative", "functional"}; return strs; } static void PassAndReceiveArrays() { int[] fibo = { 0, 1, 1, 2, 3, 5, 8, 13, 21 }; PrintArray(fibo); string[] myStrings = GetStringArray(); foreach (string s in myStrings) Console.WriteLine(s); Console.WriteLine(); } static void Main(string[] args) { PassAndReceiveArrays(); Console.ReadLine(); } } }
Output from the run is:
myIntArr[0] = 0 myIntArr[1] = 1 myIntArr[2] = 1 myIntArr[3] = 2 myIntArr[4] = 3 myIntArr[5] = 5 myIntArr[6] = 8 myIntArr[7] = 13 myIntArr[8] = 21 imperative declarative functional
Arrays we create gather much of its functionality from the System.Array class. Using these common members, we are able to operate on an array using a consistent object model. The following table shows some of its members.
Clear() | This static method sets a range of elements in the array to empty values (o for value items, static for object references). |
CopyTo() | This method is used to copy elements from the source array into the destination array. |
GetEnumerator() | This method returns the IEnumerator interface for a given array. This interface is required by the foreach construct. |
Length | This property returns the number of items within the array. |
Rank | This property returns the number of dimensions of the current array. |
Reverse() | This static method reverses the contents of a 1-dimensional array. |
Sort() | This static method sorts a 1-dimensional array of intrinsic types. If the elements in the array implement the IComparer interface, we can also sort our custom types. |
The following helper method makes use of the static Reverse() and clear() methods to get information about an array of string types to the console:
// Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyFirstCSharpCode { class Program { static void ShowSystemArrayFunctionality() { string[] Beatles = { "Let It Be", "Hey Jude", "Yesterday" }; for (int i = 0; i <= Beatles.GetUpperBound(0); i++) { Console.WriteLine(Beatles[i]); } Console.WriteLine(); Array.Reverse(Beatles); Console.WriteLine("Reversing..."); for (int i = 0; i <= Beatles.GetUpperBound(0); i++) { Console.WriteLine(Beatles[i]); } Console.WriteLine(); Array.Clear(Beatles, 1, 2); Console.WriteLine("Clearing..."); for (int i = 0; i <= Beatles.GetUpperBound(0); i++) { Console.WriteLine(Beatles[i]); } Console.WriteLine(); } static void Main(string[] args) { ShowSystemArrayFunctionality(); Console.ReadLine(); } } }
Output is:
Let It Be Hey Jude Yesterday Reversing... Yesterday Hey Jude Let It Be Clearing... Yesterday
Many members of System.Array are defined as static members and are therefore called at the class level as shown in the example: Array.Sort() or Array.Reverse() methods. Method such as these are passed in the array we want to process. Other methods of System.Array such as GetUpperBound() method or Length property are bound at the object level, and thus we are able to invoke the member directly on the array.
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization