C#方法可以定义为采用的最大参数数量是多少?


70

我试图弄清楚C#中一个方法可以拥有的最大参数数量。我到处都在寻找答案,包括C#官方文档,MSDN和一些CLR参考,但找不到答案。有人对此问题有答案吗?


10
这对于@JonSkeet是个好问题:)
蒂姆(Tim)

12
因为知道像这样的看似微不足道的问题的答案可以节省您数小时或数天的繁琐调试工作……尤其是如果自动生成的方法生成的参数数量极大(在计算机科学术语中称为arity)。
rmiesen

Answers:


63

这是您的理论答案:

为了将方法参数推入堆栈,编译后的代码具有以下MSIL操作码可供选择:

ldarg.0

ldarg.1

ldarg.2

ldarg.3

ldarg.S

ldarg

ldarg.0toldarg.3用于将前四个方法参数推入堆栈(包括this作为实例方法的第一个参数)。

ldarg.S 接受一个8位的参数号,因此可用于将多达256个参数推入堆栈。

这给我们留下了普通的old ldarg,它可以处理最多的方法参数:它需要一个无符号的16位参数号。因此,可以成功编译为有效MSIL的参数的最大数量为2^16 = 65,536

但是,正如其他人指出的那样,实际尝试执行方法时,有各种实际的堆栈大小限制,具体取决于系统的平台/体系结构。根据rmiesen的回答,看起来当前的.NET实现将运行时堆栈的最大大小限制为2^14


3
CIL还以无符号短裤存储参数数组的长度,因此长度不能超过65,535。
乔恩·汉娜

72

我使用了一个一次性程序来创建一个程序,以确定可以传递给方法的最大参数数量。根据我的实验结果,最接近答案的是以下内容(所有答案仅在我的计算机上有效):

  1. 包含一个带有16383个参数的方法的.net应用程序可以进行编译,运行和调用(!)
  2. 可以编译包含16384个或更多参数的.net应用程序,但是运行这样的程序会引发未声明的异常。
  3. 包含50000个参数的.net应用程序也可以编译,但是尝试运行这样的应用程序会导致引发StackOverflowException。
  4. 尝试编译包含100000个参数或更多参数的.net应用程序会导致csc.exe出现编译时错误,指出结果表达式太长或太复杂而无法处理。

除此之外,有人对这个问题有明确的答案吗?

PS:如果有人想在自己的计算机上尝试该实验,则可以从我的测试程序开始,该程序可以下载https://docs.google.com/open?id=0B1Q3uRTkbsXic2cwUFpXanNkSk0


17
这些数字取决于操作系统的体系结构和计算机的内存。
Ionut Hulub 2012年

3
我觉得内存将受到传递给函数的值参数数量以及参数类型的影响更大,假设您向函数中发送了16383个字符串,每个字符串的大小约为2MB,那么程序仍然可以运行而不会测试机上的异常??。我看到了@rmiesen上传的代码,里面充满了int参数。
Surya Pratap 2012年

可以传递给方法的最大参数数量可能受系统内存的限制,但这不是唯一的限制。System.Int32的大小为4个字节,所有传递的参数使用的内存为64k。附带说明一下,我做了一些数学运算,而16383比2 ^ 14小一。我想知道这在任何方面是否有意义……
rmiesen 2012年

5
0-16383的状态总数为16384(2 ^ 14),也就是价值14位。随着笑话的不断发展,这是计算机科学中的两个难题之一:缓存失效,命名和错误处理。:)
查尔斯·伯恩斯

有谁知道委托可以接受的最大参数数量是多少?
Jamshaid K.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.