假定要写方法判断作为参数传递的一组值中的最小值。一个办法是使用数组。例如:为了查找几个int值中最小的。可以写名为Min的静态方法,向其传递一个int数组,如下:
class Util
{
public static int Min(int[] paramList)
{
if(paramList == null || paramList.length == 0)
{
throw new ArgumentException("Util.Min:not enough arguments");
}
int currentMin = paramList[0];
foreach(int i in paramList)
{
if(i<<currnetmin)< p=""> currentMin )
{
currentMin=i;
}
}
}
}
为了使用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关键字声明的一个参数数组,让编译器自动生成这样的代码。
声明参数数组
参数数组允许将数量可变的实参传给方法。为了定义参数数组,要用params关键字修饰数组参数。如下
class Util
{
public static int Min(params int[] paramList)
{
if(paramList == null || paramList.length == 0)
{
throw new ArgumentException("Util.Min:not enough arguments");
}
int currentMin = paramList[0];
foreach(int i in paramList)
{
<currnetmin)< p="">if(i<<currnetmin)< p=""> currentMin )
{
currentMin=i;
}
}
}
}
在这儿,params关键字对Min方法产生的影响是:调用该方法时,可以传递任意数量的整数参数,而不必担心创建数组的问题。例如,判断两个int变量(first和second)的最小值
int min = Util.Min(first,second);
编译器自动将上述调用转换成如下代码
int[] array = new int[2];
array [0] = first;
array [1] = second;
int min = Util.Min(array );
以下代码判断三个整数那个最小,它同样被编译器转换成使用了数组的等价代码:
int min = Util.Min(first,second,third);
关于参数数组,有以下几点需要注意:
①只能为一维数组使用params关键字,不能为多维数组使用
不能只依赖params关键字来重载方法,params关键字不是方法签名的一部分,如下所示
//编译时错误:重复的声明
public static int Min(params int[] paramList)
.............
public static int Min(int[] paramList)
..................
②不允许为参数数组指定ref和out修饰符
//编译时错误
public static int Min(ref params int[] paramList)
..................
public static int Min(out params int[] paramList)
...............
③params数组必须是方法的最后一个参数。这意味着每个方法只能有一个参数数组。如下所示
//编译错误
public static int Min(params int[] paramList,int i)
④非params方法总是优先于params方法。也就是说,如果愿意,仍然可以创建方法的重载版本,让它应用于更常规的情况:
public static int Min(int leftHandSide,int rightHandSide)
.............
public static int Min(params int[] paramList)
............
调用Min时,如果传递了两个int参数值,就使用Min的第一个版本。如果传递了其他任意的int参数值(其中包括无任何参数的情况),就使用第二个版本。
使用params object[]
假如参数数量不固定,参数类型也不固定。可以让方法接收object类型的一个参数数组,从而接收任意数量的object参数,换言之,不仅参数的数量是任意的,参数类型也可以是任意的,如下:
class Black
{
public static void Hole(params object[] paramList)
.........
}
①可以不向它传递任何实参。这种情况下,编译器传递长度为0的object数组:
Black.Hole();
//转换成Black.Hole(new object[0]);
②可以在调用Black.Hole时传递null作为实参,数组是引用类型,所以允许使用null来初始化数组:
Black.Hole(null);
③可以向Black.Hole方法传递一个实际的数组。也就是说,可以手动创建本应由编译器创建的数组:
object[] array = new object[3];
array [0] = "forty two";
array [1] = 42;
Black.Hole(array);
④可向Black.Hole传递不同类型的参数,这些参数自动包装到数组中
Black.Hole("forty two",42);
//转换成Black.Hole(new object[]{"forty two",42});