0

Is there a kind of alternating params for method parameters?
I like the keyword params. But sometimes I need two parameters to be params.
I want to call a method like so:

Method(1, "a", 2, "b", 3, "c")

where 1, 2 and 3 are keys and "a", "b" and "c" are assigned values.

If I try to define the method parameters I would intuitively try to use params for two parameters like so:

void Method(params int[] i, string[] s)

Compiler would add every parameter at odd positions to the first parameter and every parameter at even positions to the second parameter.
But (as you know) params is only possible for last parameter.

Of course I could create a parameter class (e.g. KeyValue) and use it so:

Method(new[] {new KeyValue(1, "a"), new KeyValue(2, "b"), new KeyValue(3, "c")})

But that is too much code imo.

Is there any shorter notation?

Edit: Just now I found a good answer to another question: It suggests to inherit from List and to overload the Add method so that the new List can be initialized by this way:

new KeyValueList<int, string>{{ 1, "a" }, { 2, "b" }, { 3, "c" }}

Method definition would be:

void Method(KeyValueList<int, string> list)

Call would be:

 Method(new KeyValueList<int, string>{{ 1, "a" }, { 2, "b" }, { 3, "c" }})
Community
  • 1
  • 1
brgerner
  • 4,287
  • 4
  • 23
  • 38
  • If you create your parameter class (or use a `Tuple`), you could then use the `params` keyword and dispense with the enclosing `new[] { ... }`. – Kirk Woll Mar 09 '12 at 15:42
  • No there isn't anything like what you're asking for. To shorten your `KeyValue` syntax, you could use `params KeyValue[] pairs` as your parameter type. The result would be `Method(new KeyValue(1, "a"), new KeyValue(2, "b"), new KeyValue(3, "c"))`. Not much shorter though. – M.Babcock Mar 09 '12 at 15:45
  • You have Key/Value pairs and the only "correct" way is to use some form of Key/Value collection, if its "too much code" for you then think about the poor sod who might have to clean up your poor quality code at some later stage! – Lloyd Mar 09 '12 at 15:47

3 Answers3

3

There is no "alternating params" notation as you described.

You can only have one params parameter and it must be last - if you want to have different types as params parameters you can use object as the array type.

Consider passing in a list made of a custom type that retains the meaning of these items.

public class MyType
{
  public int MyNum { get; set; }
  public string MyStr { get; set; }
}

Method(List<MyType> myList);
Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 1
    Thanks. Is there an advantage **for caller** to use `List` instead of using a *params* array. – brgerner Mar 09 '12 at 15:59
  • @brgerner - Semantics and readability. You don't have type safety with `params object[] items`. – Oded Mar 09 '12 at 16:00
  • 1
    Yes. I meant compared to *Method(params MyType[] myList)*. – brgerner Mar 09 '12 at 16:04
  • @brgerner - In terms of how the call looks, not much of a difference. There are differences in the semantics inside the method, as you may have noted. This is personal style territory, more than anything. – Oded Mar 09 '12 at 16:07
1

Just giving an updated answer for today's developers looking for a solution...

Old School Answer:

You could create a class or struct that includes the parameters of the type you need...

struct Struct {
   public int Integer {get; set;}
   public string Text {get; set;}
   
   public Struct(int integer, string text) {
      Integer = integer;
      Text = text;
   }
}

... and then define your function to accept it as the params array...

void Method(params Struct[] structs)

... and call it like...

Method(new Struct(1, "A"), new Struct(2, "B"), new Struct(3, "C"));

New School Answer:

Or, with the latest C#, you could simply use ValueTuples...

Method(params (int, string)[] valueTuples)

... and call it like...

Method((1, "A"), (2, "B"), (3, "C"))
dynamichael
  • 807
  • 9
  • 9
1

You could do this via params object[] keysAndValues and sort it out yourself, but... its a bit icky, what with all the boxing/unboxing that would go on.

Jamiec
  • 133,658
  • 13
  • 134
  • 193