C#参数详解五(参数数组)

参数数组

前面所述的参数类型都必须严格地一个实参对应一个形参。参数数组则不同,它允许零个或多个实参对应一个特殊的形参。

参数数组的重点如下:

  1. 在一个参数列表中只能有一个参数数组。
  2. 如果有,它必须是列表中的最后一个。
  3. 由参数数组表示的所有参数都必须具有相同的类型。

声明一个参数数组必须做的事如下:

  1. 在数据类型前使用 params修饰符。
  2. 在数据类型后放置一组空的方括号。

下面的方法头展示了int型参数数组的声明语法。在这个示例中,形参 invasi可以代表零个或多个int实参。

void ListInts( params int[] inVals )

类型名后面的空方括号指明了参数是一个整数数组。我们需要了解的内容如下:

  1. 数组是一组整齐的相同类型的数据项。
  2. 数组使用一个数字索引进行访问。
  3. 数组是一个引用类型,因此它的所有数据项都保存在堆中。

方法调用

可以使用两种方式为参数数组提供实参:

  1. 一个逗号分隔的该数据类型元素的列表。所有元素必须是方法声明中指定的类型。
ListInts( 10, 20, 30 ); //3个int
  1. 一个该数据类型元素的一维数组。
int[] intArray = {1,2,3};
ListInts( intArray ); //一个数组变量

请注意,在这些示例中,没有在调用时使用 params修饰符。参数数组中修饰符的使用与其他参数类型的模式并不相符。

  1. 其他参数类型是一致的,要么都使用修饰符,要么都不使用修饰符。
    值参数的声明和调用都不带修饰符。
    引用参数和输出参数在两个地方都需要修饰符。
  2. params修饰符的用法总结如下
    在声明中需要修饰符。
    在调用中不允许有修饰符。

延伸式:
参数数组方法调用的第一种形式有时被称为延仲式,这种形式在调用中使用分离的实参。

例如,下面代码中的方法 ListInts的声明可以匹配它下面所有的方法调用,虽然它们有不同数目的实参。

void ListInts( params int[] inVals ) {......(方法体)} //方法声明

ListInts(); //0实参
ListInts( 1, 2, 3); //3实参
ListInts( 4, 5, 6, 7); //4实参
ListInts( 8, 9, 10, 11, 12); //5实参

在使用一个为参数数组分离实参的调用时,编译器做下面的事:

  1. 接受实参列表,用它们在堆中创建并初始化一个数组。
  2. 把数组的引用保存到栈中的形参里。
  3. 如果在对应的形参数组的位置没有实参,编译器会创建一个有零个元素的数组来使用。

例如,下面的代码声明了一个名称为 ListIntsl的方法,它带有一个参数数组。Main声明了3个整数并把它们传给了数组。

class Program
    {
        static void Main(string[] args)
        {
            int first = 5, second = 6, third = 7;//声明3个int
            MyClass mc = new MyClass();
            mc.ListInts(first, second, third);//传入实参调用方法
            Console.WriteLine("{0},{1},{2}", first, second, third);
        }
    }
    class MyClass
    {
        public void ListInts(params int[] inVals) //参数数组
        {
            if ((inVals != null) && (inVals.Length != 0))
            {
                for (int i = 0; i < inVals.Length; i++) //处理数组
                {
                    inVals[i] = inVals[i] * 10;
                    Console.WriteLine("{0}", inVals[i]); //显示新值
                }
            }
        }
    }

这段代码产生如下输出:

50
60
70
5,6,7

下图阐明了在方法执行的不同阶段实参和形参的值:

  1. 方法调用之前,3个实参已经在栈里。
  2. 在方法的开始,3个实参被用于初始化堆中的数组,并且数组的引用被赋值给形参inVals。
  3. 在方法内部,代码首先检查以确认数组引用不是null,然后处理数组,把每个元素乘以10并保存回去。
  4. 方法执行之后,形参 inVals失效。

关于参数数组,需要记住的重要一点是当数组在堆中被创建时,实参的值被复制到数组中。在这方面,它们像值参数。

  1. 如果数组参数是值类型,那么值被复制,实参不受方法内部的影响。
  2. 如果数组参数是引用类型,那么引用被复制,实参引用的对象可以受到方法内部的影响。

C#参数详解五(参数数组)_第1张图片

用数组作为实参

也可以在方法调用之前创建并组装一个数组,把单一的数组变量作为实参传递。这种情况下编译器使用你的数组而不是重新创建一个。

例如,下面代码使用前一个示例中声明的方法 ListInts。在这段代码中,Main创建一个数组,并用数组变量而不是使用分离的整数作为实参。

class Program
    {
        static void Main(string[] args)
        {
            int[] myArr = new int[] { 5, 6, 7 };//创建并初始化数组

            MyClass mc = new MyClass();
            mc.ListInts(myArr);//调用方法
            foreach (int x in myArr)
            {
                Console.WriteLine("{0}", x);
            }
        }
    }
    class MyClass
    {
        public void ListInts(params int[] inVals)
        {
            if ((inVals != null) && (inVals.Length != 0))
            {
                for (int i = 0; i < inVals.Length; i++) //处理数组
                {
                    inVals[i] = inVals[i] * 10;
                    Console.WriteLine("{0}", inVals[i]); //显示新值
                }
            }
        }
    }

这段代码产生如下输出:

50
60
70
50
60
70

你可能感兴趣的:(C#基础知识,c#)