Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass arbitrary number of named parameters to function in C#?

Is there some kind of equivalent of Python's **kwargs in C#? I would like to be able to pass variable number of named arguments into functon, then get them as something Dictionary-like inside function and cycle over them.

like image 630
src091 Avatar asked Dec 18 '12 14:12

src091


2 Answers

There is nothing in C# available to let you pass in arbitrary named parameters like this.

You can get close by adding a Dictionary<string, object> parameter, which lets you do something similar but requiring a constructor, the "parameter names" to be strings and some extra braces:

static void Method(int normalParam, Dictionary<string, object> kwargs = null)
{
   ...
}

Method(5, new Dictionary<String, object>{{ "One", 1 }, { "Two", 2 }});

You can get closer by using the ObjectToDictionaryRegistry here, which lets you pass in an anonymous object which doesn't require you to name a dictionary type, pass the parameter names as strings or add quite so many braces:

static void Method(int normalParam, object kwargs = null)
{
    Dictionary<string, object> args = ObjectToDictionaryRegistry(kwargs);
    ...
}

Method(5, new { One = 1, Two = 2 });

However, this involves dynamic code generation so will cost you in terms of performance.

In terms of syntax, I doubt you'll ever be able to get rid of the `new { ... }' wrapper this requires.

like image 101
Rawling Avatar answered Oct 12 '22 23:10

Rawling


If you specifically want a series of KeyValuePairs instead of an array of values, you could do something like this:

public class Foo
{
    public Foo(params KeyValuePair<object, object>[] myArgs)
    {
        var argsDict = myArgs.ToDictionary(k=>k.Key, v=>v.Value);
        // do something with argsDict
    }
}

myArgs would be an array of KeyValuePair<object, object> that you can iterate or convert to a dictionary as shown above. Just a note though, the conversion to dictionary might fail if you pass multiple KeyValuePair<>s with the same key. You might have to do some checking ahead of time before converting to a dictionary.

You would call it like this:

KeyValuePair<object, object> myKvp1 = new KeyValuePair<object, object>(someKey1, someValue1);
KeyValuePair<object, object> myKvp2 = new KeyValuePair<object, object>(someKey2, someValue2);
KeyValuePair<object, object> myKvp3 = new KeyValuePair<object, object>(someKey3, someValue3);

Foo foo = new Foo(myKvp1, myKvp2, myKvp3);
like image 36
psubsee2003 Avatar answered Oct 13 '22 01:10

psubsee2003