#1,123 – Using foreach to Iterate on a Multidimensional Array

You can use the foreach statement to iterate through all elements in a multidimensional array.  The elements are iterated in a row-major order.  That is, all elements in the first row are enumerated, followed by the second row, etc.

            // 2-dimensional array
            string[,] twoByThree = new string[2, 3];

            // Populate with standard for loop
            for (int row = 0; row < 2; row++)
                for (int col = 0; col < 3; col++)
                    twoByThree[row, col] = string.Format("{0}/{1}", row + 1, col + 1);

            // Iterate using foreach
            foreach (string s in twoByThree)
                Console.WriteLine(s);

1123-001

#778 – A struct Isn’t Mutable When Used in a Collection

struct is normally mutable, i.e. you can modify the values of its members directly.

However, if a struct is used in a collection class, like a List<T>, you can’t modify its members.  Referencing the item by indexing into the collection returns a copy of the struct, which you can’t modify.  To change an item in the list, you need to create a new instance of the struct.

            List<DogCollarInfo> collarList = new List<DogCollarInfo>();

            // Create a few instances of struct and add to list
            collarList.Add(new DogCollarInfo(0.5, 14.0));
            collarList.Add(new DogCollarInfo(0.3, 12.0));

            // Compile-time error: Can't modify '...' because it's not a variable
            collarList[1].Length = 22.0;

            // Do this instead
            collarList[1] = new DogCollarInfo(collarList[1].Width, 22.0);

If you store the structs in an array, then you can change the value of one of the struct’s members.

            DogCollarInfo[] arr = new DogCollarInfo[2];
            arr[0] = new DogCollarInfo(0.5, 14.0);
            arr[0].Length = 5.0;  // OK

#774 – Passing an Array as an out Parameter

Like other reference types, you can use an array as an output parameter, using the out keyword.  The out keyword indicates that you must assign a value to the array before returning from the method.  Also, within the method, you cannot reference the array parameter before you assign a new value to it.

        static int FindFibsThrough(int numFibs, out int[] fibs)
        {
            // Can't reference element of array
            //int i = fibs[0];

            // Can't assign to element of array
            //fibs[0] = 12;

            if (numFibs < 2)
                throw new Exception("Must return at least 2 numbers in sequence");

            // Must assign new value to array before we return
            fibs = new int[numFibs];

            fibs[0] = 0;
            fibs[1] = 1;
            int sum = 1;

            for (int i = 2; i < numFibs; i++)
            {
                fibs[i] = fibs[i - 1] + fibs[i - 2];
                sum += fibs[i];
            }

            return sum;
        }

You must also use the out keyword when calling the method.

            int[] myFibs;
            int sum = FindFibsThrough(10, out myFibs);

774-001

#650 – Creating an Array of Anonymously-Typed Objects

An anonymous type is a temporary data type that is inferred based on the data that you include in an object initializer.  In addition to creating a single anonymously-typed object with an object initializer, you can also create an array of objects.

            var movies = new[] {
                new { Title = "North By Northwest", Year = 1959, Director = "Alfred Hitchcock" },
                new { Title = "Zelig", Year = 1983, Director = "Woody Allen" },
                new { Title = "King Kong", Year = 2005, Director = "Peter Jackson" }};

With this declaration, you end up with an array of anonymously-typed objects, each of which has the properties Title, Year, and Direction.

Note that this implicitly-typed array must contain elements of the same type, so each element must have the exact  same set of properties.

#600 – Reversing the Elements in an Array

You can use the static Array.Reverse method to reverse the order of elements in an array.  This modifies the contents of the array that you pass to Array.Reverse.

            int[] someNumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            DumpArrayContents(someNumbers);

            // Reverse the elements using Array.Reverse
            Array.Reverse(someNumbers);
            DumpArrayContents(someNumbers);

Note that this Reverse method is different from the IEnumerable<int>.Reverse method, which does not modify the contents of the array, but just returns a reversed sequence.

// IEnumerable<int>.Reverse
int[] moreNumbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> reversedNums = moreNumbers.Reverse();
DumpArrayContents(moreNumbers);
DumpArrayContents(reversedNums);

#597 – Returning an Array from a Method

You can return an array from a method just like you can return any other reference-typed object from a method.  The array will be instantiated within the method and a reference to the new object is what is returned to the calling code.

Assume that we have a method declared like this in a Dog class:

public string[] FavoriteToys()

We can then call this method as follows:

            Dog kirby = new Dog("Kirby", 15);

            string[] favToys = kirby.FavoriteToys();

            foreach (string toy in favToys)
                Console.WriteLine(toy);


We could also just use the method call in the body of the foreach loop:

            foreach (string toy in kirby.FavoriteToys())
                Console.WriteLine(toy);

#572 – Why Array Covariance Is Called Covariance

Array covariance in C# allows you to assign an array of instances of a derived class to a variable whose type is an array of instances of the base class.

Dog[] dogs = hounds;     // Where hounds is Hound[] and Hound is subclass of Dog

Covariance says that the ordering of two elements in a set is preserved after transforming each by the same function.

With array covariance, we can think of the “ordering” as being the fact that the subtype is narrower than the base class, which means that the assignment is allowed due to assignment compatibility.

The covariant function being applied to each type is to create an array of that type.  This “function”, an array of a type, is then covariant because if type T is narrower than type U, then T[] is also narrower than U[], preserving assignment compatibility.

#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[]

#277 – Passing an Array to a Method

A variable that is the name of an array is just a reference to an instance of System.Array.  Since it is a reference type, when you pass an array to a method, you pass a copy of the reference.  This means that the method has the ability to read and write elements of the array.

Here’s a method that accepts an array as an input parameter.  The code demonstrates that you can read from and write to elements of the array.

        public static void DumpMovieInfo(MovieInfo[] movieList)
        {
            for (int i = 0; i < movieList.Length; i++)
            {
                // Read element of the array
                Console.WriteLine("{0} ({1}), {2}", movieList[i].Title, movieList[i].Year, movieList[i].Director);

                // Rewrite element
                movieList[i].Title = movieList[i].Title.ToUpper();
                movieList[i].Director = movieList[i].Director.ToUpper();
            }
        }

You would call the method as follows:

            MovieInfo[] movies = { new MovieInfo("The African Queen", 1951, "John Huston"),
                                   new MovieInfo("Casablanca", 1942, "Michael Curtiz"),
                                   new MovieInfo("The Godfather", 1972, "Francis Ford Coppola")};

            Movie.DumpMovieInfo(movies);

            Movie.DumpMovieInfo(movies);

#148 – Getting the Average of an Array of Custom Objects

If you want to calculate the average (mean) of a collection of objects stored in an array, you can use the IEnumerable.Average method.

The Average method allows passing in an indication of the function that should be used to calculate the numeric value from each object, which will be used in generating the average.  This function takes an object whose type matches the type of the array as an input parameter and returns a numeric value, used in generating the average.  It will be called once for each element of the array.

You could define a static function and pass a delegate to that function.

        static int AgeOf(Person p)
        {
            return p.Age;
        }

        // Example of calling Average on Person[] array
        double avgAge = folks.Average((Func<Person,int>)AgeOf);

Alternatively, you could use a lambda expression, avoiding the need to define a separate function.

            double avgAge = folks.Average(person => person.Age);