5

I need to write a function that will take a variable number of arguments. I read a little about params[], but I don't think that will work in my case. My function needs to take a variable number of ints and then a corresponding bool value for each of them. I have to iterate through each of these combinations and input them into a database. Just looking for someone to point me in the right direction. Thanks.

Christopher Garcia
  • 2,536
  • 7
  • 30
  • 40

4 Answers4

16

I would recommend building a struct and then passing those in as params. In my example, your struct represents a score of some kind:

public struct RaceScore
{
     public bool FinishedRace;
     public int Points;
}

Your method signature would then be:

public void SaveScores(params RaceScore[] scores)

Here's an example of calling SaveScores:

RaceScore score = new RaceScore() { FinishedRace = true, Points = 20 };
RaceScore score2 = new RaceScore() { FinishedRace = false, Points = 15 };
SaveScores(score, score2);
Matt Brindley
  • 9,739
  • 7
  • 47
  • 51
  • 2
    It should be noted that a struct is really only appropriate for a couple of variables. A class is better suited for anything more than that. – Jason Baker May 27 '09 at 16:18
  • Just out of curiosity, why would a struct be inappropriate for more than a few variables? – Christopher Garcia May 27 '09 at 16:30
  • 1
    Partly because of the pass-by-value semantics of structs: whenever you pass one into a method, a copy is created, which is more expensive than passing a reference (which is what would happen if you were passing a reference type instead). – Ant May 27 '09 at 16:49
11

You can do this with params, but the params needs to be some class or struct that holds your int + your bool. KeyValuePair<TKey,TValue> in the base class libraries would work, if you don't want to write your own class or struct.

If you're going to iterate through them, though, I'd recommend using IEnumerable<T> instead, though, as it's much simpler to use.

For example:

public void SaveValues(IEnumerable<KeyValuePair<int,bool>> values)
{
    foreach(var pair in values)
    {
        int intVal = pair.Key;
        bool boolVal = pair.Value;
        // Do something here...
    }
}

The same thing would work with params, ie:

public void SaveValues(params KeyValuePair<int,bool>[] values)

This, though, forces you to make an array. Using IEnumerable<T> will work with an array, but will also work with lists of values, or LINQ query results, etc. This makes generating calling this function easier in many cases.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    +1. Better solution than my dictionary answer, I should not have assumed that the integers were IDs. – Brandon May 27 '09 at 16:23
  • 1
    This sounds like it would be perfect, but I don't think it's available in 1.1, which is what I'm restricted to with this project. I should've noted that. – Christopher Garcia May 27 '09 at 16:31
5

That is right - it will not work as described. What you could do is to use a struct to join the int and the bool value. Params of structs are working:

public struct IntBoolStruct {
   public bool BoolValue;
   public int IntValue;
}

public void YourMethod( params IntBoolStruct[] values ) {}

EDIT: Depending of what you want to do, a nullable int might help you, too.

public void YourMethod( params int?[] values ) {}
tanascius
  • 53,078
  • 22
  • 114
  • 136
0

And another answer: you can do this with a simple object-array and params.

    class paramstest {
        private void _passALot(params Object[] values) {
            System.Console.WriteLine(" [foreach]");

           foreach (object o in values) {
                System.Console.Write(o.ToString() + ", ");
            }

            System.Console.WriteLine(System.Environment.NewLine + " [for]");

            for (int i = 0; i < values.Length; i += 2) {
                int? testval = values[i] as Int32?;
                bool? testbool = values[i + 1] as Boolean?;

                System.Console.WriteLine(String.Format("Int: {0}, Bool: {1}", testval, testbool));
            }
        }

        public void test() {
            _passALot(1, true, 2, false, 3, true, "q", false);
        }
    }

giving you

[foreach]
1, True, 2, False, 3, True, q, False,
 [for]
Int: 1, Bool: True
Int: 2, Bool: False
Int: 3, Bool: True
Int: , Bool: False

Passing a Dictionary or a List with an appropriate struct would be better though :)

Leonidas
  • 2,440
  • 15
  • 22