#1,016 – Retrieving the Length of an Array

You can use the Length property of an array to get the number of elements in the array.

For a one- or multi-dimensional arrays, the length is always the total number of elements.  For a jagged array (array of arrays), the length is the number of elements in the outer dimension.

            int[] someNumbers = { 5, 16, 12, 38, 78, 63 };
            // Length = 6
            Console.WriteLine(someNumbers.Length);

            int[,] twoDimensional = { { 3, 2, 1 }, { 1, 2, 3 }, { 4, 6, 8 } };
            // Length = 9
            Console.WriteLine(twoDimensional.Length);

            int[][] jagged = new int[3][] {
                new int[] { 1, 2, 3 },
                new int[] { 4, 8 },
                new int[] { 10, 20, 30, 40 } };
            // Length = 3
            Console.WriteLine(jagged.Length);

1016-001

Advertisement

#1,012 – Options for Array Declaration, Instantiation and Initialization

Recall that there are three steps for using arrays:

  • Declare the array (declare a variable whose type is an array)
  • Instantiate the array (allocate memory for the array)
  • Initialize the array (store values in the array)

Below are examples of the different ways that you can declare, instantiate, and initialize an array.

            // Option 1: Declare, instantiate and initialize in three
            //   steps
            int[] a1;
            a1 = new int[3];
            a1[0] = 1; a1[1] = 2; a1[2] = 3;

            // Option 2: Declare in 1 step, instantiate/initialize in
            //   2nd step
            int[] a2;
            a2 = new int[] {1, 2, 3};

            // Option 3: Declare and instantiate in 1 step,
            //   initialize later.
            int[] a3 = new int[3];  // Must provide size
            a3[0] = 1; a3[1] = 2; a3[2] = 3;

            // Option 4: Declare, instantiate and initialize
            //   in single line. (Using array initializer)
            int[] a4 = new int[] { 1, 2, 3 };

            // Variation: Can omit type
            int[] a5 = new[] { 1, 2, 3 };

            // Variation: Can omit new keyword, inferring type
            int[] a6 = { 1, 2, 3 };

#772 – Initializing an Array as Part of a Method Call

When you want to pass an array to a method, you could first declare the array and then pass the array by name to the method.

Suppose that you have a Dog method that looks like this:

        public void DoBarks(string[] barkSounds)
        {
            foreach (string s in barkSounds)
                Console.WriteLine(s);
        }

You can declare the array and pass it to the method:

            Dog d = new Dog();

            // Declare array and then pass
            string[] set1 = { "Woof", "Rowf" };
            d.DoBarks(set1);

Or you can just initialize a new array instance as part of the method call, without first declaring it:

            // Initialize and pass array without declaring
            d.DoBarks(new string[] { "Grr", "Ack-ack" });

You can also initialize a multi-dimensional array as part of a method call:

            // Initialize and pass multi-dimensional array
            d.AddNumbers(new int[,] { { 1, 2, 3 }, { 9, 10, 11 }, { 100, 12, 32 } });

772-001

#599 – Copying an Array Onto Another Array

You can use the Array.CopyTo method to copy one entire array into another array.  The first array must be the same size or smaller than the second array.

You specify the index into the second array where you want to start copying the first array.  (0 indicates the first element of the second array).  The portion of the second array starting at this index must be large enough to contain the entire first array.

        static void Main()
        {
            int[] bigNumbers = {400, 500, 600};
            int[] smallerNumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            // Copy big number array into middle of small number array
            // Start at 4th element (index = 3)
            bigNumbers.CopyTo(smallerNumbers, 3);

            // Dump them both out
            DumpArrayContents(bigNumbers);
            DumpArrayContents(smallerNumbers);
        }



Note that if the portion of the destination array that starts at the specified index is not large enough to contain the source array, you will get an ArgumentException.

You can only use CopyTo with one-dimensional arrays.

#598 – Clearing an Array or a Subset of an Array

You can clear (zero out) an array or a subset of an array with a call to the static Array.Clear method.  You pass the array into the method, as well as an indication of what portion of the array you want to clear.

Dog kirby = new Dog("Kirby", 15);
string[] someToys = kirby.FavoriteToys();
int[] someNumbers = kirby.FavoriteNumbers();

DumpArrayContents(someToys, someNumbers);

// Now clear each array
Array.Clear(someToys, 0, someToys.Length);  // Clear entire array
Array.Clear(someNumbers, 1, 2);   // Clear 2nd/3rd elements
DumpArrayContents(someToys, someNumbers);

Notice that after we call Clear on the array of string elements, each element becomes an empty string.  For the array of int values, the two elements that we cleared become zero.

If you call Array.Clear on an array contained reference-typed objects, the values that are cleared become null.

Dog[] pack = { new Dog("Kirby", 15), new Dog("Jack", 17), new Dog("Ruby", 1) };

DumpArrayContents(pack);

Array.Clear(pack, 0, pack.Length);
DumpArrayContents(pack);

#573 – Array Covariance Doesn’t Apply to Value Types

Array covariance allows T[] to be assigned to U[], if can be assigned to U.

// Assignment compatibility, because Terrier is sub-type of Dog
Terrier t = new Terrier("Bob");
Dog d = t;

// Allowed because of array covariance
Terrier[] terriers = MakeTerrierArray();
Dog[] dogs = terriers;

This does not work, however, if the contents of the arrays are value types.  Arrays of value-typed objects are not covariant.

            byte b1 = 12;
            ushort u1 = b1;  // Assignment compatible

            byte[] bytearray = new byte[] { 1, 2, 3 };

            // Not allowed.  Compile-time error "Cannot implicitly convert type 'byte[]' to 'ushort[]'
            ushort[] shortarray = bytearray;

#280 – Implicitly-Typed Arrays

In the same way that you can declare an implicitly-typed variable, letting the compiler figure out the type of the variable’s value, you can declare implicitly-typed arrays.

In the example below, we declare and initialize both implicitly-typed variables and implicitly-typed arrays.  The compiler infers the type–shown in the associated comment.

            // Implicitly-typed variables
            var x = 42;         // int
            var s = "Hooey";    // string

            // Implicitly-typed arrays
            var someArray = new[] { 5, 6, 7 };             // int[]
            var arrB = new[] { new Dog("Bob"), null };     // Dog[]

#279 – Passing a Multidimensional Array to a Method

You can pass multi-dimensional arrays to methods.  Like arrays with a single dimension, the array is passed by value, with a copy of the reference passed to the method.  This means that the method can change elements in the array.

Here’s an example of a method that takes a two-dimensional array as an input parameter.

        public static void CountPawns(ChessPiece[,] chessboard, out int redPawns, out int blackPawns)
        {
            redPawns = 0;
            blackPawns = 0;

            for (int row = 0; row < 8; row++)
                for (int col = 0; col < 8; col++)
                {
                    ChessPiece piece = chessboard[row,col];
                    if (piece != null)
                    {
                        if (piece.PieceType == PieceTypeEnum.Pawn)
                        {
                            if (piece.PieceColor == PieceColorEnum.Red)
                                redPawns++;
                            else
                                blackPawns++;
                        }
                    }
                }
        }

When calling the method, you just pass the name of the array to the method.

            ChessPiece[,] board = new ChessPiece[8, 8];

            board[0, 1] = new ChessPiece(PieceTypeEnum.King, PieceColorEnum.Red);
            // continue to set up board here

            int redPawns;
            int blackPawns;
            Chess.CountPawns(board, out redPawns, out blackPawns);

#278 – Passing an Array by Reference

You can pass an array by reference to a method, using the ref or out parameter modifier, when you want the method to change the parameter to refer to a different array.

Here’s an example of a method that accepts an array and then overwrites the reference so that it points to a new array.

        public static void DoubleADogList(ref Dog[] list)
        {
            Dog[] bigList = new Dog[2 * list.Count()];

            int i2 = 0;
            foreach (Dog d in list)
            {
                bigList[i2++] = new Dog(d.Name, d.Age, d.Motto);
                bigList[i2++] = new Dog(d.Name + " Clone", d.Age, d.Motto);
            }

            // Change original reference to refer to new list
            list = bigList;
        }

We can call this method, passing it an array. When the method returns, the array variable points to the new (larger) array.

            Dog d1 = new Dog("Kirby", 13, "Chase balls");
            Dog d2 = new Dog("Jack", 17, "Bark");

            Dog[] list = new Dog[] { d1, d2 };

            Dog.DoubleADogList(ref list);

 

#155 – Iterating Through an Array Using the foreach Statement

You can write a loop–a block of code that is executed more than once–that executes once for each element in an array, using the C# foreach statement.

The foreach statement declares a variable local to the loop of the same type of the elements in the array.  This variable takes on the value of each element in the array.

            Person[] folks = new Person[4];
        	folks[0] = new Person("Bronte", "Emily");
	        folks[1] = new Person("Bronte", "Charlotte");
	        folks[2] = new Person("Tennyson", "Alfred");
	        folks[3] = new Person("Mailer", "Norman");

            string sLastNameList = "";

            // For each Person in array, dump out name and concatenate last name
            foreach (Person p in folks)
            {
                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
                sLastNameList += p.LastName;
            }