1.使用数组参数
假定要写方法判断作为实参传递的- 组值中的最小值。一个办法是使用数组。例如,为了查找几个int值中最小的,可以写名为Min的静态方法,向其传递一个int数组,如下所示:
class Util
{
public static int Min(int[] paramList)
{
//验证调用者至少提供了一个参数。
//否则抛出ArgumentExceptlon异常,
//因为不可能在空列表中查找最小值
if (paramList ==null II paramlist.Length == 0)
{
throw new ArguentExcepton("Util.Min: not enough arguments");
}
//将参数列表的第项设为当前最小值
int currentMin =paramList[0];
//遍历参数列表,检查是否有一个值比currentMin小
foreach (int i in paramList)
{
//找到比currentMin小的就把它把设为currentMtin的值
if (i < currentMin)
{
currentMin = i;
}
}
//循环结束后currentMin必然容纳参数列表中的最小值,所以直接返回它
return currentMin;
}
}
用Min方法判断两个int变量(first和second)的最小值可以这样写:
int[] array = new int[2];
array[0] = first;
array[1] = second;
int min = Util.Min(array);
用Min方法判断三个int变量(first, second 和third)的最小值可以这样写:
int[] array = new int[3];
array[0] = first;
array[1] = second;
array[2] = third;
int min = Util.Min(array);
可以看出,这个方案避免了对大量重载的需求,但也为此付出了代价:必须写额外的代码来填充传入的数组。当然,也可以像下面这样使用匿名数组:
int min = Util.Min(new int[] {first, second, third);
但本质没变,仍需创建和填充数组,而且这个语法还有点儿不容易理解。解决方案是向Min方法传递用params关键字声明的一个参数数组,让编译器自动生成这样的代码。
1.1声明参数数组
参数数组允许将数量可变的实参传给方法。
下面是修改过的Min方法,这次它的数组参数被声明成参数数组:
class Util
{
public static int Min()
{
//这里的代码和以前完全一样
}
}
调用:
int min = Util.Min(first,second);
编译器自动将上述调用转换成如下所示的代码:
int[] array = new int[2];
array[0] = first;
array[1] = second;
int min = Uti1.Min(array);
以下代码判断三个整数哪个最小,它同样被编译器转换成使用了数组的等价代码:
int min = Util.Min(first, second, third);
注意事项:
(1)只能为一维数组使用params关键字,不能用于多维数组。
(2)不能只依赖params关键字来重载方法。params关键字不是方法签名的一部分,如下例所示:
//编译时错误:重复的声明
public static int Min(int[] paramList)
…
public static int Min(params int[] paramList)
…
(3)不允许为参数数组指定ref或out修饰符。
(4)params数组必须是方法最后一个参数。这意味着每个方法只能有一个参数数组。
(5)非params方法总是优先于params方法。
1.2使用params object[]
如果参数数量不固定,参数类型也不固定,怎么办?
答:可以让方法接收object类型的一个参数数组,从而接收任意数量的object实参,object是所有类的根,编译器通过装箱将值类型转换成对象。
class Black
{
public static void Hole(params object [] paramList)
}
(1)不向它传递任何实参,这时编译器传递长度为0的object数组:
Black.Hole();//转换成Black.Hole(new object[0]);
(2)传递null作为实参,数组是引用类型,所以允许使用null来初始化数组:
Black.Hole(null);
(3)传递一个实际的数组。也就是说,可以手动创建本应由编译器创建的数组:
object[] array - new object[2];
array[0] = "forty two";
array[1] = 42;
Black.Hole(array);
(4)传递不同类型的实参,这些实参自动包装到object数组中:
Black.Hole("forty two", 42);//转换成Black.Hole(new object[]{"forty two", 42});
2.比较参数数组和可选参数
(1)获取可选参数的方法仍然有固定参数列表,不能传递一组任意的实参。编译器会
生成代码,在方法运行前,为任何遗漏的实参在栈上插入默认值。方法不关心哪些实参是由调用者提供的,哪些是由编译器生成的默认值。
(2)使用参数数组的方法相当于有一个完全任意的参数列表,没有任何参数有默认值。此外,方法可准确判断调用者提供了多少个实参。
通常,如果方法要获取任意数量的参数(包括0个),就使用参数数组。只有在不方便强迫调用者为每个参数都提供实参时才使用可选参数。
参考书籍:《Visual C#从入门到精通》