如何为方法创建命名的`params`参数?

时间:2015-02-26 10:33:51

标签: c# .net

C#有一个很好的params关键字,用于将任意数量的参数传递给String.Format()等函数。但是如果我需要传递命名参数(键值对)呢?最好的方法是什么(我在调用者方面寻找一个简短的语法)?

  • func(new Dictionary<string, object> { { "param1", val1 }, { "param2", val2 } }过于繁琐
  • func(param1 => val1, param2 => val2)func(new { param1 = val1, param2 = val2 })但它看起来像滥用语言而且这些功能不应该像那样使用
  • on dynamic个对象我可以解析可选参数名func(param1: val1, param2: val2),它看起来像是一个很好的解决方案但不适用于常见的对象方法

3 个答案:

答案 0 :(得分:2)

你可以创建一些函数重载。当调用者端只有1或2个参数时,这些重载将封装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)
{
}

答案 1 :(得分:0)

如果.NET Framework 4适合您,也许您可​​以使用Tuple

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

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

<强> [编辑]

另一种方法是将每个人都作为对象:

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只能使用一次。并且它传递的数据类型是唯一的。使用params,您可以:

  • 使用通用类型object
  • 使用元组

您无法通过不同类型传递任意长的参数列表。

如果您承认,为了保留类型,您必须将您的东西放在一些新的容器中,最便宜的方法是使用其中两种。

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

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

答案 2 :(得分:0)

具有您想要制作的API的库的一个示例是iTween。它在一些游戏开发圈中众所周知,因此不能认为这种做法很糟糕。

它使用辅助函数来创建传递给main函数的哈希表。你这样称呼它:

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

它是开源的,所以如果你想搜索“itween.cs”,你可以查看它。辅助函数采用params object[] args参数列表,并确保每个参数列表都是有效类型,然后将其放入Hashtable中。参数名称(必须是字符串),然后参数(在您的情况下,这将是一个对象)。 main函数将作为Hashtable的元素访问参数。

根本不是类型安全的。但我认为这是你要求的唯一方法。