Receiving undefined number of parameters in C #

7

The Main(string[] args) method receives an array of indefinite quantity parameters. But I know this does not work in a common method. How do I create a method that receives how many parameters are needed?

    
asked by anonymous 01.05.2014 / 22:04

2 answers

7

You can do this using the params keyword. You set a parameter that uses multiple arguments or none.

For example:

    private static int Somar(params int[] values)
    {
        int sum = 0;

        for (int i = 0; i < values.Length; i++)
        {
            sum += values[i];
        }

        return sum;
    }

And with this, you can call Somar() as follows:

    static void Main(string[] args)
    {
        Console.WriteLine("O resultado da soma é " + Somar(1, 2, 3, 4, 5));
        Console.WriteLine("Outro resultado da soma é " + Somar(10, 20, 4));
        Console.WriteLine("Quando não soma nada é " + Somar());

        Console.Read();
    }

It should be noted that the parameter with params must be the last one in the function. For example:

// A seguite declaração é inválida:
private static void Imprimir(params int[] valores, string titulo) { }

// Já essa é válida (pois params vai por último):
private static void Imprimir(string titulo, params int[] valores) { }

Another important detail is that the compiler will give priority to the specialized version of the method (if one exists).

For example, if you have the following defined methods:

private static int Somar(int a, int b) { }
private static int Somar(params int[] values) { }

and calling Somar(10, 20) , the compiler will give priority to the first one.

Another special case is when you want to use params for various types. In this case, object is used instead of the specific type.

An example is as follows:

public static void ImprimirLista(params object[] list)
{
    for (int i = 0; i < list.Length; i++)
    {
        Console.Write(list[i] + " ");
    }

    Console.WriteLine();
}

Which is applied like this:

ImprimirLista(10, "String", 20.4);

When comparing methods that use params to methods that do not use params , you should consider that the params keyword is treated by the compiler so that when it is called Somar(2, 3, 4) , the compiler turns into Somar(new int[]{2,3,4}) . Without params , the compiler will not make that consideration and will require a int[] .

Therefore, setting the following methods will result in a conflict because they are equivalent:

 public static void ImprimirLista(params int[] list) {}
 public static void ImprimirLista(int[] list) {}
    
01.05.2014 / 22:11
5

Lucas Nunes's answer is correct and very complete. I will only offer alternatives that may be useful to others today and in the future.

It may not be necessary to have a completely indeterminate number of parameters. You can have a variable amount but have a small maximum limit. And it may be that each parameter has a different known type. There are some alternatives in these cases.

void M(int p1 = 1, string p2 = "", bool p3 = true, int p4 = 0) { ... }

This form uses optional arguments . So in the method call it is possible to use only the parameters that are not equal to the default values. Ex.:

M(2); //na prática chama M(2, "", true, 0)

In addition, you can use the named arguments call:

void M(p1: 1, p4: 0, p3: true)

There is still a way to explicitly pass parameters in this way:

void M(Tuple<int, string, bool, int> p) { ... }

The call would stay:

M(new Tuple<int, string, bool, int>(3, "teste", false, 1));

In C # it's also possible:

M(new Tuple(3, "teste", false, 1));

In some situations you may not want to receive an array exactly. There are proposals to use an enumerable type, it almost went into C # 6 and 7. Who knows in 8.

void M(params IEnumerable<int> p) { foreach(int i in p) Console.WriteLine(i); }

In C # 7 has tuples in the language , which may make it even easier:

void M((int valor, string nome, bool status, int outro) p) { ... }

The call would stay:

M((3, "teste", false, 1));
    
06.05.2014 / 13:38