Previous Page
Next Page

Using Array Arguments

Suppose you want to write a method to determine the minimum value in a set of parameters. One way would be to use an array. For example, to find the smallest of several int values, you could write a static method called Min with a single parameter representing an array of int values:

class Util
{
    public static int Min(int[] paramList)
    {
        if (paramList == null || paramList.Length == 0)
        {
            throw new ArgumentException("Util.Min");
        }
        int currentMin = paramList [0];
        foreach (int i in paramList)
        {
            if (i < currentMin) 
            {
                currentMin = i;
            }
        }
        return currentMin;
    }
}

To use the Min method to find the minimum of two int values, you would write this:

int[] array = new int[2];
array[0] = first;
array[1] = second;
int min = Util.Min(array);

And to use the Min method to find the minimum of three int values, you would write this:

int[] array = new int[3];
array[0] = first;
array[1] = second;
array[2] = third;
int min = Util.Min(array);

You can see that this solution avoids the need for a large number of overloads, but it does so at a price: You have to write additional code to populate the array passed in. However, you can get the compiler to write some of this code for you by using the params keyword to declare a params array.

Declaring params Arrays

You use the params keyword as an array parameter modifier. For example, here's Min again, this time with its array parameter declared as a params array:

class Util
{
    public static int Min(params int[] paramList)
    {
        // code exactly as before
    }
}

The effect of the params keyword on the Min method is that it allows you to call it by using any number of integer arguments. For example, to find the minimum of two integer values, you would write this:

int min = Util.Min(first, second);

The compiler translates this call into code similar to this:

int[] array = new int[2];
array[0] = first;
array[1] = second;
int min = Util.Min(array);

To find the minimum of three integer values, you would write the code shown below, which is also converted by the compiler into the corresponding code that uses an array:

int min = Util.Min(first, second, third);

Both calls to Min (one call with two arguments and another with three arguments) resolve to the same Min method with the params keyword. And as you can probably guess, you can call this Min method with any number of int arguments. The compiler just counts the number of int arguments, creates an int array of that size, fills the array with the arguments, and then calls the method by passing the single array parameter.

NOTE
C and C++ programmers might recognize params as a type-safe equivalent of the varargs macros from the header file stdarg.h.

There are several points worth noting about params arrays:

Using params object[ ]

A params int array is very useful because it allows any number of int arguments in a method call. However, what if not only the number of arguments varies, but also the argument type? C# has a way to solve this problem, too. The technique is based on the facts that System.Object (object) is the root of all classes, and that the compiler can generate code that converts value types (things that aren't classes) into objects by using boxing, as described in Chapter 8, “Understanding Values and References.” You can use a params object array to declare a method that accepts any number of arguments of objects, allowing the arguments passed in to be of any type. Look at this example:

class Black
{
    public static void Hole(params object [] paramList) 
    ...
}

I've called this method Black.Hole, not because it swallows every argument, but because no argument can escape from it:

Using params Arrays

In the following exercise, you will implement and test a static method called Util.Sum. The purpose of this method is to calculate the sum value of a variable number of int arguments passed to it, returning the result as an int. You will do this by writing Util.Sum to take a params int[] parameter. You will implement two checks on the params parameter to ensure the Util.Sum method is completely robust. You will then call the Util.Sum method with a variety of different arguments to test it.

Write a params array method
  1. Start Visual Studio 2005.

  2. Open the ParamsArray project, located in the \Microsoft Press\Visual CSharp Step by Step\Chapter 11\ ParamArrays folder in your My Documents folder.

  3. Display the Util.cs source file in the Code and Text Editor window.

    The Util.cs file contains an empty class called Util in the ParamsArray namespace.

  4. Add a public static method called Sum to the Util class.

    The Util.Sum method returns an int and accepts a params array of int values. Util.Sum should look like this:

    class Util
    {
        public static int Sum(params int[] paramList)
        {
        }
    }

    The first step in implementing Util.Sum is to check the paramList parameter. Apart from containing a valid set of integers, it could also be null or it could be an array of zero length. In both of these cases, it is difficult to calculate the sum, so the best option is to throw an ArgumentException. (You could argue that the sum of the integers in a zero-length array is zero, but we will treat this situation as an exception in this example.)

    NOTE
    The ArgumentException class is specifically designed to be thrown by a method if the arguments supplied do not meet the requirements of the method.
  5. Add a statement to Util.Sum that throws an ArgumentException if paramList is null.

    Util.Sum should now look like this:

    public static int Sum(params int[] paramList)
    {
        if (paramList == null)
        {
            throw new ArgumentException("Util.Sum: null parameter list");
        }
    }
  6. Add a statement to Util.Sum that throws an ArgumentException if the length of array is 0.

    Util.Sum should now look like this:

    public static int Sum(params int[] paramList)
    {
        if (paramList == null)
        {
           throw new ArgumentException("Util.Sum: null parameter list");
        }
    
        if (paramList.Length == 0) 
        {
           throw new ArgumentException("Util.Sum: empty parameter list");
        }
    }

    If the array passes these two tests, the next step is to add all the elements inside the array together. You can use a foreach statement for this step. You will also need a local variable to hold the sum value.

  7. Add a foreach statement to Util.Sum to add all the elements in the array together, and then return it from Util.Sum with a return statement.

    Util.Sum should now look like this:

    class Util
    {
        public static int Sum(params int[] paramList)
        {
            ...
            int sumTotal = 0;
            foreach (int i in paramList)
            {
                sumTotal += i;
            }
            return sumTotal;
        }
    }
  8. On the Build menu, click Build Solution. Confirm that there are no errors in your code.

Test the Util.Sum method
  1. In the Code and Text Editor window, open the Program.cs source file.

  2. In the Code and Text Editor window, locate the Entrance method in the Program class.

  3. Add the following statement to the Entrance method:

    Console.WriteLine(Util.Sum(null));
  4. On the Debug menu, click Start Without Debugging.

    The program builds and runs, writing the following message to the console:

    Exception: Util.Min: null parameter list

    This confirms that the first check in the method works.

  5. Press the Enter key to finish the program return to Visual Studio 2005.

  6. In the Code and Text Editor window, change the call to Console.WriteLine in Entrance to the following statement:

    Console.WriteLine(Util.Sum());

    This time, the method is being called without any arguments. The compiler will translate the empty argument list into an empty array.

  7. On the Debug menu, click Start Without Debugging.

    The program builds and runs, writing the following message to the console:

    Exception: Util.Min: empty parameter list

    This confirms that the second check in the method works.

  8. Press the Enter key to finish the program and return to Visual Studio 2005.

  9. Change the call to Console.WriteLine in Entrance to the following:

    Console.WriteLine(Util.Sum(10,9,8,7,6,5,4,3,2,1));
  10. On the Debug menu, click Start Without Debugging.

    The program builds, runs, and writes 55 to the console.

  11. Press Enter to close the application.

In this chapter, you have learned how to use a params array to define a method that can take variable numbers of arguments. You have also seen how to use a params array of object types to pass arguments of different types.


Previous Page
Next Page