C#传递参数

与函数交换数据的最好方式就是传递参数,在C#中有四种方法来控制参数如何传递给目标方法

C#中的参数修饰符

无修饰 如果一个参数没有用参数修饰符,则认为它将按值传递
out 输出参数由被调用的方法赋值。因此它按引用传递
ref 调用者赋初值,并且可以由被调用的方法可选地重新赋值,因此数据也是按照引用传递的
params 将一组可变数据的参数作为单独的逻辑参数进行传递

下面来一一介绍

默认传参

 static int Multiply(int a, int b)
         {
              int ans = a * b;
             a = 100;
             b = 315;
             return ans;
          }

在主函数中进行调用

 static void Main(string[] args)
          {
              Console.WriteLine("**********默认传参行为********\n");
              int a = 19, b = 25; 
              Console.WriteLine("调用之前的:a={0},b={1}", a, b);
             Console.WriteLine("调用函数的结果:{0}", Multiply(a, b));  
              Console.WriteLine("调用之后的: a={0},b={1}", a, b);
              Console.WriteLine();
              Console.ReadKey();
          }

输出结果:

image

通过输出结果可知:a和b的值,在调用函数Multiply(int a, int b) 前后的值保持不变,虽然在Multiply(int a, int b)函数内部试图修改a和b的值,但实际上修改的只是a,b值的副本;a,b原来的值不变

输出参数out

out修饰,即定义为输出参数,当定义为输出参数时,必须在退出方法之前给参数一个恰当的值,否则会产生编译错误

以下是带out参数的方法

static void FunWithOut(int x,int y,out int ans)
       {
           ans = x + y;
       }

调用一个带有输出参数的方法,也必须是用out修饰符。需要注意的是:作为输出变量的本地变量不需要赋值,否则原来的值会丢失

 FunWithOut(110, 120, out ans);
            Console.WriteLine("110+120={0}", ans);
            Console.ReadKey();

我们知道使用return 一次只能返回一个返回值,而使用out参数则可以通过一次调用,获取多个返回值


例如:

 static void ReturnValues(out int a,out int b,out string c,out bool d)
        {
            a = 120;
            b = 119;
            c = "This is a demo";
            d = false;

        }
 Console.WriteLine("**********带有out参数,输出多个值********\n");
            int a; int b; string c; bool d;
            ReturnValues(out a, out b, out c, out d);
            Console.WriteLine("输出结果:\n a={0}\n b={1}\n c={2}\n d={3}\n",a,b,c,d);
            Console.ReadKey();

image

引用参数ref

引用参数,可以对调用者作用域中声明的不同数据进行操作。比如可以用引用参数来实现排序和交换等操作

下面是交换两个值的实例:

 public static void SwapValues(ref int a,ref int b)
        {
            int temp = a;
            a = b;
            b = temp;
        }
调用函数
static void Main(string[] args)
        {
            Console.WriteLine("**********带有ref参数********\n");
            int a = 123;
            int b = 456;
            Console.WriteLine("调用之前的:a={0}  b={1}", a, b);
            SwapValues(ref a, ref b);
            Console.WriteLine("调用之后的:a={0}  b={1}", a, b);
            Console.ReadKey();
            
            
        }

image

参数数组params

使用params修饰符可以把相同类型可变数量的参数作为一个逻辑参数传递给方法,比如下面的函数,可以接收任意个int类型的数,并且返回它的平均值

static int ReturnAverage(params int[] values)
        {
            Console.WriteLine("参数数组的长度{0}", values.Length);
            int sum = 0;
            if(values.Length==0)
            {
                return sum;
            }
            for(int i=0;i<values.Length;i++)
            {
                sum += values[i];
            }
            return (sum / values.Length);
        }
static void Main(string[] args)
        {
            Console.WriteLine("**********带params的参数数组********\n");
            int average;
            Console.WriteLine("**********用列表调用********\n");
            average = ReturnAverage(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
            Console.WriteLine("传入参数的平均值为{0}", average);

            Console.WriteLine("**********用数组调用********\n");

            int[] data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            Console.WriteLine("传入参数的平均值为{0}", ReturnAverage(data));
            Console.ReadKey();

          }
C#语言中,要求方法只能有一个params参数修饰符

可选参数

可选参数允许我们对传入的参数提供默认值,可选参数必须放在参数列表的最后
 class Program
    {
        static void EnterLogData(string message,string owner="Programer")
        {
            Console.Beep();
            Console.WriteLine("Error:{0}", message);
            Console.WriteLine("Owner of Error:{0}", owner);
        }
        static void Main(string[] args)
        {
            //调用含可选参数的函数
            EnterLogData("Oh no ! Grid can't find data ");
            EnterLogData("Oh no ! I can't find the payroll data", "CFO");
            Console.ReadKey();
        }
    }

在上面的两次调用中:
第一次调用中,没有显式指定第二个string的值,第二个参数采用默认值即"Programer"
第二次调用中,显式指定了owner的值为"CFO"

需要注意的是可选参数的值必须在编译时就确定好,而不能再运行时,才确定

命名参数



posted @ 2014-06-15 18:15  漫长当下  阅读(661)  评论(0编辑  收藏  举报