Poma
Poma

Reputation: 8494

How to make named `params` arguments for methods?

C# has a great params keyword for passing arbitary number of arguments to functions such as String.Format(). But what if I need to pass named parameters (key-value pairs)? What is the best method for that (I'm looking for a short syntax on callers side)?

Upvotes: 2

Views: 352

Answers (3)

piojo
piojo

Reputation: 6723

One example of a library with an API like the one you want to make is iTween. It's well known in some game dev circles, so the practice can't be considered that bad.

It uses a helper function to create a hash table that's passed to the main function. You call it like this:

iTween.MoveTo(camera, iTween.Hash("path", iTweenPath.GetPath("CamPath"), "looktarget", player,
                                  "looktime", 0f, "speed", 2, "easetype", iTween.EaseType.linear));

It's open source, so you can look it if you want to search for "itween.cs". The helper function takes a params object[] args argument list, and makes sure each one is a valid type, then puts it in a Hashtable. Argument name (must be a string), then argument (in your case, this will be an object). The main function will access the arguments as elements of the Hashtable.

It's not type safe at all. But I think it's the only way to do what you're asking for.

Upvotes: 0

Orace
Orace

Reputation: 8359

If.NET Framework 4 is ok for you, maybe you can use Tuple

void MyFunction(params Tuple<string, int>[] p)

// Example of call
MyFunction(Tuple.Create("pipo", 1), Tuple.Create("poil", 2)); // Matthew Mcveigh

[Edit]

An other way is to cast everybody as object:

void MyFunction(params object[] data)
{
    for (var i = 0; i < data.Length; i += 2)
    {
        var s = (string) (data[i]);
        var k = (int) (data[i+1]);

        ...
    }
}

...

// Example of call
MyFunction("pipo", 1, "poil", 2);

params can only be used once. And the type of the data passed by it is unique. With params you can either:

  • Use the generic type object
  • Use a tuple

There is no way that you can just pass an arbitrary long list of parameters with different type.

If you admit that, for preserving the type, you have to put your stuffs in some new container the cheapest way is to use two of them.

void MyFunction(string[] names, int[] values)

// Example of call
MyFunction(new[] {"pipo", "poil"}, new[] {1, 2});

Upvotes: 0

ASh
ASh

Reputation: 35733

you can create some overloads of function. when there are only 1 or 2 parameters on caller-side, those overloads will encapsulate usage of Dictionary

public void Foo (string paramA, object valueA)
{
   this.Foo(new Dictionary<string, object> { { paramA, valueA } });
}

public void Foo (string paramA, object valueA, string paramB, object valueB)
{
   this.Foo(new Dictionary<string, object> { { paramA, valueA },{ paramB, valueB } });
}

public void Foo (Dictionary<string, object> args)
{
}

Upvotes: 2

Related Questions