我可以传递任意数量的命名参数来在C#中运行吗?

时间:2012-12-18 14:01:14

标签: c# function named-parameters

在C#中是否有某种类似Python的**kwargs?我希望能够将可变数量的命名参数传递给functon,然后将它们作为类似于字典的内部函数并循环遍历它们。

5 个答案:

答案 0 :(得分:12)

C#中没有任何内容可以让您传递任意命名的参数。

你可以通过添加一个Dictionary<string, object>参数来接近,它允许你做类似但需要构造函数的东西,“参数名称”是字符串和一些额外的括号:

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

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

使用the ObjectToDictionaryRegistry here可以让您更接近,它允许您传入一个匿名对象,该对象不需要您命名字典类型,将参数名称作为字符串传递或添加相当多的大括号:

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

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

然而,这涉及动态代码生成,因此会在性能方面降低成本。

在语法方面,我怀疑你是否能够摆脱这需要的“新{...}”包装。

答案 1 :(得分:2)

如果你特别想要一系列KeyValuePairs而不是一系列值,你可以这样做:

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将是KeyValuePair<object, object>的数组,您可以迭代或转换为字典,如上所示。但请注意,如果您使用相同的密钥传递多个KeyValuePair<>,则转换为字典可能会失败。在转换为字典之前,您可能需要提前进行一些检查。

你会这样称呼:

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);

答案 2 :(得分:0)

void paramsExample(object arg1, object arg2, params object[] argsRest)
{
    foreach (object arg in argsRest)
    { /* .... */ }
}

这样称呼,

paramsExample(1, 0.0f, "a string", 0.0m, new UserDefinedType());

答案 3 :(得分:0)

您可以使用参数列表作为函数的最终参数,如下所示:

void paramsExample(object arg1, object arg2, params object[] argsRest) {
    foreach (object arg in argsRest)
    { /* .... */ }
}

可以使用任意类型的任意数量的参数调用该方法。

paramsExample(1, 0.0f, "a string", 0.0m, new UserDefinedType());

这是一个强类型参数,所以如果我想使用字符串列表,我可以这样做:

 public string Concat(string separator, params string[] strings) {
      string result = "";
      for (int i = 0; i < strings.Length; i++) {
          if (i > 0)
              result += separator;
          result += strings[i];
      }    
      return result;
 }

要调用:

MessageBox.Show(Concat("+", "Anders", "Eric", "Scott", "Duncan") + " = great team");

点击此处查看更多信息: http://blogs.msdn.com/b/csharpfaq/archive/2004/05/13/how-do-i-write-a-method-that-accepts-a-variable-number-of-parameters.aspx

答案 4 :(得分:0)

是。我相信,C#4.0中增加了使用可选参数和命名参数的能力。

http://msdn.microsoft.com/en-us/library/dd264739(v=vs.100).aspx