views:

131

answers:

2

I am curious and hopefully someone can shed somelight on this - but why do the C# functions that take 'params' have to be an array?

I get that the objects in the parameters list are entered into an array but what if someone wants to create a variadic function that takes in an undefined number of array objects?

Take this function for example...

private Int32 Sum(params Int32[] numbers)
{
    return numbers.Sum(); // Using LINQ here to sum
}

Pretty straight forward, it can take in a different amount of numbers - for example...

Int32 x = Sum(1);
Int32 y = Sum(1, 2);
Int32 z = Sum(1, 2, 3);

Now lets say I want to create a function that takes in a different amount of Integer arrays and sums up all the numbers. As far as I am aware I would have to consider boxing...

private Int32 SumArrays(params Object[] numbers)
{
    Int32 total = 0;
    foreach (Object o in numbers)
    {
        Int32[] array = (Int32[])o;

        total += array.Sum();
    }
    return total;
}

Which could then be used like...

Int32[] arr1 = new Int32[] { 1, 2, 3 };
Int32[] arr2 = new Int32[] { 1, 2, 3, 4 };
Int32[] arr3 = new Int32[] { 1, 2, 3, 4, 5 };

Int32 x = SumArrays((Object)arr1, (Object)arr2);
Int32 y = SumArrays((Object)arr1, (Object)arr2, (Object)arr3);

What was the reasoning behind this? Why wasn't this ever implemented as just a single non array variable? Such as params Int32?

+2  A: 

The functionality is already there, no need to resort to boxing:

private int SumAll(params int[][] args)
{
    int result = 0;
    for (int x = 0; x < args.Length; x++)
    {
        for (int y = 0; y < args[x].Length; y++)
        {
            result += args[x][y];
        }
    }
    return result;
}

You just need to add it an array of arrays.

Fredrik Mörk
Ah cool didnt know that, but why is this the case, because its not really an array of arrays is it? It's more just a list of arrays, why not just params Int32 for a list of numbers, and params Int32[] for an array?
Chalkey
@Chalkey: yes it an array of arrays. If you examine args in the debugger, it will look like this: args = {int[2][]}. Each element of the args array is an int array.
Fredrik Mörk
A: 

The params get rolled into a single object, and the lowest-level object that can hold a collection is an array. If you want a function that takes a variable number of arrays of ints, then it should be declared as taking an array of int arrays.

static int SumArrays(params int[][] data)
{
    int rval = 0;
    for (int i = 0; i < data.Length; i++)
    {
        rval += data[i].Sum();
    }
    return rval;
}
Yuliy
Why use a half-LINQ solution if you can use a full-LINQ solution - `return data.Sum(array => array.Sum());`.
romkyns