在c#中调用参数量未知的函数

Calling a function with unkown amout of parameter in c#

我有一个功能

public static SomeFunction(string a, string b = "", string c = "", string d = "")
{
return a + b + c + d;
}

我有未知数量的字符串 (1-4) 存储在列表中(也可以以不同方式存储)。

即使我实际上不知道列表中会有多少项,我现在如何使用字符串调用 SomeFunction()?

功能已给定,无法更改。

void SomeFunction(params string[] val) 允许您传递任意数量的字符串参数,这些参数在函数内部被视为数组。如果你想传递任何东西,你可以在 params 关键字后使用 object[]

如果像这样,您的功能会得到更好的服务:

public static string SomeFunction(IEnumerable<string> values)
{
    return string.Concat(values);
}

然后可以将其传递给 List<string>string[] 或其他可枚举的字符串并将其连接起来,尽管通过向 [=21 添加抽象层实际上并没有做太多事情=],所以在这种情况下我会完全放弃该函数,只使用内置函数。

编辑

如果不能像你说的那样修改方法,那么还有另一种选择,你可以这样做:

public static string SomeFunctionInvoker(IEnumerable<string> values)
{
    var listStr = values.ToArray();    //<-- Requires System.Linq

    if (listStr.Length > 4)
        throw new ArgumentException("Too many arguments provided");

    if (listStr.Length == 0)
        throw new ArgumentException("Not enough arguments provided");

    string[] strArray4 = new string[4];

    Array.Copy(listStr, strArray4, listStr.Length);

    return SomeFunction(strArray4[0], strArray4[1], strArray4[2], strArray4[3]);
}

基本上,这里发生的事情是您将 IEnumerable<string> 传递给调用程序函数,以确保参数数量适合 SomeFunction 参数列表。然后它创建一个具有最大参数数量的数组,将原始数组复制到其中,然后将所有参数传递给 SomeFunction.

这仅在 SomeFunction 的默认参数使用 string.Emptynull 作为默认值时有效。如果它有其他默认值,then the only way to get the default values and pass them in without knowing at compile time is to use reflection.

这个呢

    List<string> list = new List<string> { "aaa", "bbb" };

    switch(list.Count){
        case 1: SomeFunction(list[0]);break;
        case 2: SomeFunction(list[0], list[1]);break;
        case 3: SomeFunction(list[0], list[1], list[2]);break;
        case 4: SomeFunction(list[0], list[1], list[2], list[3]);break;
        default: throw new ArgumentException("List length out of range");
    }

嗯,简单的事情就是把它包起来:

string MyFunctionEx(IList<string> values) {
   switch (values.Length) {
       case 1:
          return MyFunction(values[0]);
       case 2:
          return MyFunction(values[0], values[1]);
       case 3:
          return MyFunction(values[0], values[1], values[2]);
       case 4:
          return MyFunction(values[0], values[1], values[3], values[4]);
       break:
          throw new InvalidOperationException();
}

大概您正在寻找比这更通用的东西?好吧,在那种情况下,我通常会说 dynamic 是可行的方法 - 不幸的是,由于这是一个 static 方法,你没有那么奢侈,将不得不使用反射。需要注意的一点是可选参数仍然需要传递,但应该是 Type.Missing:

object[] parameters = new object[4];
for (var i = 0; i < parameters.Length; i++) {
     parameters[i] = i < myList.Count ? myList[i] : Type.Missing;
}
MethodInfo mi = typeof(SomeClass).GetMethod(nameof(SomeClass.SomeFunction));
string result = (string)mi.Invoke(null, parameters);

假设 + 你的意思是加入而不是将它们添加为数字我会推荐一些快速简单的东西,比如:

public string joinMyStrings(List<string> values) 
{
     return string.Join("", values);  // add any dividers if wanted
}