Reputation: 8494
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)?
func(new Dictionary<string, object> { { "param1", val1 }, { "param2", val2 } }
is too cumbersomefunc(param1 => val1, param2 => val2)
and func(new { param1 = val1, param2 = val2 })
but it looks like language abuse and those features are not supposed to be used like thatdynamic
objects I can parse optional parameters names func(param1: val1, param2: val2)
which looks like a good solution but is doesn't work for common object methodsUpvotes: 2
Views: 352
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
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:
object
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
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