zoukankan      html  css  js  c++  java
  • C#的参数类型:params、out和ref

    parmas类型的参数

     1 using System;
     2 public class MyClass
     3 {
     4     public static void UseParams(params int[] list)
     5     {
     6         for (int i = 0 ; i < list.Length; i++)
     7         {
     8             Console.WriteLine(list[i]);
     9         }
    10         Console.WriteLine();
    11     }
    12     public static void UseParams2(params object[] list)
    13     {
    14         for (int i = 0 ; i < list.Length; i++)
    15         {
    16             Console.WriteLine(list[i]);
    17         }
    18         Console.WriteLine();
    19     }
    20     static void Main()
    21     {
    22         UseParams(1, 2, 3);
    23         UseParams2(1, 'a', "test");
    24         int[] myarray = new int[3] {10,11,12};
    25         UseParams(myarray);
    26     }
    27 }

    上面的代码运行后将会输出

    1
    2
    3

    1
    a
    test

    10
    11
    12

    当需要传递多个参数,或参数个数不定的时候,就可以用params类型的参数。

    params类型的参数搭配数组使用,实现一个不定长的数组参数 
    最常用的应该是Console.WriteLine,其中有一个重载如下: 
    public static void WriteLine(string FormatString, params object[] values); 
    常见的调用方式:Console.WriteLine("宽:{0},高:{1}",this.Width,this.Height); 
    前面的"宽:{0},高:{1}"被装入FormatString 
    this.Width,this.Height被装入values[0]和values[1]之中,如果我们再加几个参数上去,那将按下标继续存入数组中

     

    ref关键字

    ref 关键字使参数按引用传递。其效果是,当控制权传递回调用方法时,在方法中对参数的任何更改都将反映在该变量中。若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。例如:

     1 class RefExample
     2 {
     3     static void Method(ref int i)
     4     {
     5         i = 44;
     6     }
     7     static void Main()
     8     {
     9         int val = 0;
    10         Method(ref val);
    11         // val is now 44
    12     }
    13 }

    传递到 ref 参数的参数必须最先初始化。这与 out 不同,后者的参数在传递之前不需要显式初始化。

    如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两个参数,则可以进行重载,如下例所示:

    class RefOutOverloadExample
    {
    public void SampleMethod(int i) { }
    public void SampleMethod(ref int i) { }
    }

    属性不是变量,因此不能作为 ref 参数传递。

    ref类型的参数是指在将一个变量做为一个参数传递给某个方法的时候,使用引用传递。 
    如果变量是值类型的话,ref和out起的效果是一样,只是ref参数在使用前必须先赋值,而out不用。 
    定义方法: 
    void Test(ref int v1,ref float v2) 

      v1 = 1; 
      v2 = 0.5f; 

    调用方法: 
    int a = 0; 
    float b = 0; 
    Test(ref a,ref b); 
    ---------------------无敌分隔线--------------------- 
    ref比较容易混淆的地方在于如果参数是引用类型的变量时,处理的结果与直接传一个引用类型变量有什么区别? 
    测试类: 
    public class Class1 

      public int X = 0; 
      public int Y = 5; 

    定义方法: 
    private void Test(Class1 c) 
    {//直接传引用类型 
      c.Y = 10; 
      c.X = 10; 
      //非ref传递,这句改不了引用的内存空间 
      c = new Class1(); 

    private void Test(ref Class1 c) 
    {//通过ref传引用,允许被调用的方法修改 该引用 所 引用的对象,因为引用本身是按引用来传递的。 
      c.Y = 10; 
      c.X = 10; 
       
      //c通过ref传递,这里c会变成一个新的Class1 
      c = new Class1(); 

    调用方法: 
    Class1 a = new Class1(); 
    Test(a); 
    Console.WriteLine("X:{0},Y:{1}",a.X,a.Y); 
    Class1 b = new Class1(); 
    Test(ref b); 
    Console.WriteLine("X:{0},Y:{1}",b.X,b.Y); 
    输出结果: 
    X:10,Y:10 
    X:0,Y:5 
    通过输出结果我们可以看到使不使用ref的区别 
    用ref的话,c可以更改指向,从而放弃它原来所引用的那块内存空间 
    如果不用的话,只能改c内存空间中的数据,不可以更改指向。

    out关键字

    out 关键字会导致参数通过引用来传递。这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。例如:

     1 class OutExample
     2 {
     3     static void Method(out int i)
     4     {
     5         i = 44;
     6     }
     7     static void Main()
     8     {
     9         int value;
    10         Method(out value);
    11         // value is now 44
    12     }
    13 }

    尽管作为 out 参数传递的变量不必在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。

    属性不是变量,因此不能作为 out 参数传递。

    out类型的参数做为输出参数使用,用于一个方法返回多个值类型的变量,一般对值类型使用。 
    定义方法: 
    void Test(out int v1,out float v2) 

      v1 = 1; 
      v2 = 0.5f; 

    调用方法: 
    int a; 
    float b; 
    Test(out a,out b); 
    基本上和Sql Server的output参数一样 

    以上内容引自微软MSDN

  • 相关阅读:
    What is Split Brain in Oracle Clusterware and Real Application Cluster (文档 ID 1425586.1)
    Oracle Grid Infrastructure: Understanding Split-Brain Node Eviction (文档 ID 1546004.1)
    代理模式和装饰者模式区别
    偏向锁、轻量级锁、重量级锁
    理解HTTP幂等性
    Java8 lambda表达式10个示例
    IDEA debug断点调试技巧
    【1】【leetcode-115 动态规划】 不同的子序列
    【leetcode-91 动态规划】 解码方法
    【leetcode-78 dfs+回溯】 子集
  • 原文地址:https://www.cnblogs.com/Jacklovely/p/5654244.html
Copyright © 2011-2022 走看看