Microsoft.NET

……………………………………………….Expertise in .NET Technologies

Arrays in C#

Posted by Ravi Varma Thumati on May 11, 2009

An array represents a fixed number of elements of a particular type. The elements in an array are always stored in a contiguous block of memory, providing highly efficient access.

An array is denoted with square brackets after the element type. For example:

               char[] vowels = new char[5];   // Declare an array of 5
               characters

Square brackets also index the array, accessing a particular element by position:             
               vowels [0] = ‘a’;
               vowels [1] = ‘e’;
               vowels [2] = ‘i’;
               vowels [3] = ‘o’;
               vowels [4] = ‘u’;
               Console.WriteLine (vowels [1]);    // e

This prints “e” because array indexes start at zero. We can use a for loop statement to iterate through each element in the array. The for loop in this example cycles the integer i from 0 to 4:

               for (int i = 0; i < vowels.Length; i++)
                 Console.Write (vowels [i]);               // aeiou

Arrays also implement IEnumerable<T>, so you can enumerate members with the foreach statement:

               foreach (char c in vowels) Console.Write (c);   // aeiou

 The Length property of an array returns the number of elements in the array. Once an array has been created, its length cannot be changed. The System.Collection namespace and subnamespaces provide higher-level data structures, such as dynamically sized arrays and dictionaries.

An array initialization expression specifies each element of an array. For example:

               char[] vowels = new char[] {'a','e','i','o','u'};

All arrays inherit from the System.Array class, which defines common methods and properties for all arrays. This includes instance properties such as Length and Rank, and static methods to:

  • Dynamically create an array (CreateInstance)
  • Get and set elements regardless of the array type (GetValue/SetValue)

Search a sorted array (BinarySearch) or an unsorted array (IndexOf, LastIndexOf, Find, FindIndex, FindLastIndex)

  • Sort an array (Sort)

·         Copy an array (Copy)

Default Element Initialization

Creating an array always preinitializes the elements with default values. The default value for a type is the result of a bitwise-zeroing of memory. For example, consider creating an array of integers. Because int is a value type, it allocates 1,000 integers in one contiguous block of memory. The default value for each element will be 0:

               int[] a = new int[1000];
               Console.Write (a[123]);          // 0

Value types versus reference types

Whether an array element type is a value type or a reference type has important performance implications. When the element type is a value type, each element value is allocated as part of the array. For example:

               public struct Point { public int X, Y; }
               ...
              
               Point[] a = new Point[1000];
               int x = a[500].X;                  // 0

 Had Point been a class, creating the array would have merely allocated 1,000 null references:

               public class Point { public int X, Y; }
              
               ...
               Point[] a = new Point[1000];
               int x = a[500].X;          // Runtime error
                                         // (NullReferenceException)

 To avoid this error, we must manually instantiate 1,000 Point objects after instantiating the array:

               Point[] a = new Point[1000];
               for (int i = 0; i < a.Length; i++)    // Iterate i from
                                                     // 0 to 999
                  a[i] = new Point( );               // Set array element
                                                     // i with new point

 An array itself is always a reference type object, regardless of element type:

               int[] a = null;    // Legal - int[] is reference type

 Multidimensional Arrays

Multidimensional arrays come in two varieties: rectangular and jagged. Rectangular arrays represent an n-dimensional block of memory, and jagged arrays are arrays of arrays.

Rectangular arrays

Rectangular arrays are declared using commas to separate each dimension. The following declares a rectangular twodimensional array, where the dimensions are 3 by 3:

               int[,] matrix = new int [3, 3];

 The Get Length method of an array returns the length for a given dimension (starting at 0):

               for (int i = 0; i < matrix.GetLength (0); i++)
                 for (int j = 0; j < matrix.GetLength (1); j++)
                   matrix [i, j] = i * 3 + j;

A rectangular array can be initialized as follows (each element in this example is initialized to be identical to the previous example):

               int[,] matrix = new int[,]
               {
                 {0,1,2},
                 {3,4,5},
                 {6,7,8}
               };

Jagged arrays

Jagged arrays are declared using successive square brackets to represent each dimension. Here is an example of declaring a jagged two-dimensional array, where the outermost dimension is 3:

               int [][] matrix = new int [3][];

 The inner dimensions aren’t specified in the declaration. Unlike a rectangular array, each inner array can be an arbitrary length. Each inner array is implicitly initialized to null rather than an empty array. Each inner array must be created manually:

               for (int i = 0; i < matrix.Length; i++)
               {
                 matrix[i] = new int [3];       // create inner array
                 for (int j = 0; j < matrix[i].Length; j++)
                   matrix[i][j] = i * 3 + j;
               }

 A jagged array can be initialized as follows (each element in this example is initialized to be identical to the previous example):

               int[][] matrix = new int[][]
               {
                 new int[] {0,1,2},
                 new int[] {3,4,5},
                 new int[] {6,7,8}
               };

Simplified Array Initialization Expressions

There are two ways to shorten array initialization expressions; the first is to omit the new operator and type qualifications:

               char[] vowels = {'a','e','i','o','u'};
              
               int[,]rectangularMatrix =
               {
                 {0,1,2},
                 {3,4,5},
                 {6,7,8}
               };
              
               int[][]jaggedMatrix =
               {
                 new int[] {0,1,2},
                 new int[] {3,4,5},
                 new int[] {6,7,8}
               };

 In C# 3.0, the second approach is to use the var keyword, which tells the compiler to implicitly type a local variable:

               var i = 3;           // i is implicitly of type int
               var s = "sausage";   // s is implicitly of type string
              
               // Therefore:
              
               var rectMatrix = new int[,] // rectMatrix is implicitly
               {                           // of type int[,]
                 {0,1,2},
                 {3,4,5},
                 {6,7,8}
               };
              
               var jaggedMat = new int[][] // jaggedMat is implicitly
               {                           // of type int[][]
                 new int[] {0,1,2},
                 new int[] {3,4,5},
                 new int[] {6,7,8}
               };

 Implicit typing can be taken one stage further with single-dimensional arrays. You can omit the type qualifier after the new keyword, and have the compiler infer the array type:

               // Compiler infers char[]
 
               varvowels =new[]{'a','e','i','o','u'};

 The elements must have identical types for implicit array typing to work. For example:

               var x = new[] {1, "a"};         // Error, elements are of
                                           // multiple types

Bounds Checking

All array indexing is bounds-checked by the runtime. An IndexOutOfRangeException is thrown if you use an invalid index:

               int[] arr = new int[3];
               arr[3] = 1;          // IndexOutOfRangeException thrown

 Like with Java, array bounds checking is necessary for type safety, and it simplifies debugging.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: