string.Format()参数

时间:2009-02-18 13:19:53

标签: c# language-features

你可以传递给string.Format()方法多少个参数?

必须有某种理论或强制限制。它是基于params []类型的限制还是正在使用它的应用程序的内存使用情况?

4 个答案:

答案 0 :(得分:19)

据我所知......

好吧,理论上的限制是数组的int32限制,但是在那之前很久你就达到了字符串长度限制,我猜...

不要生气它;-p最好将大量小片段写入(例如)文件或响应,而不是一次大打击。

编辑 - 看起来就像IL(0xf4240)中有限制一样,但显然这并不像它出现的那样;在我用完系统内存之前,我可以让它变得非常大(2 ^ 24)...


更新;在我看来,边界点是格式字符串...那些{1000001} {1000002}加起来...快速的数学运算(如下)显示最大有用数量的参数我们可以使用的是206,449,129:

    long remaining = 2147483647;// max theoretical format arg length
    long count = 10; // i.e. {0}-{9}
    long len = 1;
    int total = 0;
    while (remaining >= 0) {
        for(int i = 0 ; i < count && remaining >= 0; i++) {
            total++;
            remaining -= len + 2; // allow for {}
        }
        count *= 10;
        len++;
    }

    Console.WriteLine(total - 1);

答案 1 :(得分:19)

好吧,我隐藏了......我使用以下程序来验证发生了什么,而Marc指出像这样的字符串“{0} {1} {2} ... {2147483647}”在争论列表之前会接受2 GiB的内存限制,我的发现与你的不匹配。因此,您可以在string.Format方法调用中放入的参数数量的硬限制必须 107713904

int i = 0;
long sum = 0;
while (sum < int.MaxValue)
{
    var s = sizeof(char) * ("{" + i + "}").Length;
    sum += s; // pseudo append
    ++i;
}
Console.WriteLine(i);
Console.ReadLine();

热爱讨论的人!

答案 2 :(得分:4)

扩展Marc的详细答案。

唯一重要的其他限制是调试器。将一定数量的参数直接传递给函数后,调试器在该方法中的功能就会降低。我认为限制是64个参数。

注意:这并不意味着一个包含64个成员的数组,而是直接传递给该函数的64个参数。

你可能会笑并说“谁会这样做?”这当然是一个有效的问题。然而LINQ比你想象的要容易得多。在LINQ的引擎下,编译器会生成大量代码。对于大型生成SQL查询,可能会选择超过64个字段,您可能会遇到此问题。因为引擎盖下的编译器需要将所有字段传递给匿名类型的构造函数。

仍然是一个角落案件。

答案 3 :(得分:3)

考虑到Array类和String类的限制都是Int32的上限(在此处记录为2,147,483,647:Int32 Structure),可以合理地认为此值是数字字符串的限制格式参数。

更新检查反射器时,John是对的。 String.Format,使用红门反射器,显示ff:

public static string Format(IFormatProvider provider, string format, params object[] args)
{
    if ((format == null) || (args == null))
    {
        throw new ArgumentNullException((format == null) ? "format" : "args");
    }
    StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));
    builder.AppendFormat(provider, format, args);
    return builder.ToString();
}

代码的format.Length + (args.Length * 8)部分足以杀死大部分数字。 Ergo,'2,147,483,647 = x + 8x'给我们留下x = 238,609,294(理论值)。

当然远不及那个;正如评论中的人提到的那样,字符串早先达到字符串长度限制很可能。

也许有人应该把它编码成机器问题! :P