C/C++和C#中的不定参数

目录

C#中的params

首先,在C#中,我们一般是使用params关键字来处理不定参数的问题,对于params的用法这里不再赘述。
我们先来写一小段测试代码来看看C#中params是如何运作的:
C/C++和C#中的不定参数
我们使用ILSpy来进行反编译,得到它的IL代码:
C/C++和C#中的不定参数
C/C++和C#中的不定参数
由上图我们可以看到,ParamsTest和ArrayTest的参数都是一个int32的数组,并没有任何区别,ParamsTest只比ArrayTest多了如下IL代码:
C/C++和C#中的不定参数
可以看到,.param[1]不清楚是什么指令,这里猜测是取得函数的第一个参数,然后调用了一次ParamArrayAttribute的构造器,查看微软给出的文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.paramarrayattribute?redirectedfrom=MSDN&view=netframework-4.7.2 ,其中有这样一段话(这里放上中英双语版本):
C/C++和C#中的不定参数
C/C++和C#中的不定参数
也就是说,在C#中,如果我们使用了params关键字,实际上就是在使用ParamArrayAttribute,那么也就是说,这两行IL代码实际上是取得了第一个参数,然后用它来构建了ParamArrayAttribute,ParamArrayAttribute的源码如下所示:C/C++和C#中的不定参数
再返回main函数中查看调用过程:
C/C++和C#中的不定参数
我们可以很清晰地发现,当编译器发现了params关键字时,会将new一个数组,用所有参数来填充这个数组,然后将这个数组传入函数中,同时会调用一次ParamArrayAttribute的构造器。因此在实际开发中,不必要的params的使用也是产生GC的一个原因。

C/C++中的不定参数

C/C++中常常使用的printf,scanf等函数就是在使用不定参数,在代码中以如下方式(三个点"…")存在:
C/C++和C#中的不定参数
未完待续…