文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C# 中ref 与 out 总结

C# 中ref 与 out 总结

时间:2010-10-22  来源:Eric Sun

  在C#中实现“引用传递”的两种方式为:ref 和 out。当然这两种方式也有他们的不同,下面将逐步讲解他们的不同之处。

  1. 使用ref关键字进行“引用传递”时,传入的实参必须先被初始化,这就像C和C++中的指针一样,一定要先给它赋值(让它指向一个指定的内存位置),要不然它不一定会指向内存的哪里,这样很危险,不允许。而使用out关键字进行“引用传递”时,传入的实参不必先初始化。如下面的例子所示:
     1using System;
    2using System.Collections.Generic;
    3using System.Linq;
    4using System.Text;
    5
    6namespace RefAndOut
    7{
    8 class RefAndOutTesting
    9 {
    10 static void Main(string[] args)
    11 {
    12 int x;
    13 int y;
    14 OutTest(out x, out y);
    15 Console.WriteLine(string.Format("x = {0}, y = {1}", x, y));
    16
    17 int a = 100;
    18 int b = 200;
    19 RefTest(ref a, ref b);
    20 Console.WriteLine(string.Format("a = {0}, y = {1}", a, b));
    21 }
    23 //out参数在使用前不必初始化
    24 public static void OutTest(out int first, out int second)
    25 {
    27 first = 1;
    28 second = 2;
    29 }
    30 //ref参数在使用前必须初始化
    31 public static void RefTest(ref int first, ref int second)
    32 {
    33 first = 1111;
    34 second = 2222;
    35 }
    36 }
    37}

     

  2. 虽然使用out关键字进行“引用传递”时,传入的实参不必先初始化,但是在函数中一定要先对参数进行初始化,之后再使用。因为:在使用out参数的时候,程序首先将out的实参(形参)置空,(因此实质上实参先初始化了对此函数也没有用)然后再对参数进行相应的操作;由于置空了,所以在离开该函数之前必须完成参数的初始化(即使你不对参数做任何操作),要不然该参数的指针又不知道该指向何处了。假如变化一下上面的OutTest函数:
    1         public static void OutTest(out int first, out int second)
    2 {
    3 first = second;
    4 //first = 1;
    5 //second = 2;
    6 }
    便会提示你:Use of unassigned out parmeter 'second'。即使你先初始化实参再去调用也会出现同样的错误(原因就是out先对参数进行清空操作)
     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace OutAndRef
    7 {
    8 class Program
    9 {
    10 static void Main(string[] args)
    11 {
    12 //out变量在使用之前不必进行显示的赋值
    13 int x = 1111;
    14 int y = 2222;
    15 OutTest(out x, out y);
    16 Console.WriteLine("x = {0}, y = {1}", x, y);
    17 }
    18
    20 public static void OutTest(out int x, out int y)
    21 {
    22 //离开这个函数前,必须对x和y赋值,否则会报错。
    23 x = y;
    24 //上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋过值也不行
    25 x = 1;
    26 y = 2;
    27 }
    29 }
    31 }
    32

     

  3. 因此上面的两点可以总结为:ref有出有进,out有出没进。
  4. 使用ref和out进行“引用传递”,在定义方法和调用方法时,都要在参数前加ref和out关键字,以满足匹配。
  5. 由于属性是方法,不是变量;而指针是变量。所以属性都不可以作为ref和out参数传递。如果在上面的RefAndOutTesting类中声明两个属性,传递给RefTest和OutTest方法中,则会出错!
     1 using System;
    2 using System.Collections.Generic;
    3 using System.Linq;
    4 using System.Text;
    5
    6 namespace RefAndOut
    7 {
    8 class RefAndOutTesting
    9 {
    10 //属性(是方法,不是变量)所以不可以作为ref和out参数
    11 public static int firstNumber
    12 {
    13 get;
    14 set;
    15 }
    16 public static int secondNumber
    17 {
    18 get;
    19 set;
    20 }
    21
    22 //字段可以作为ref和out参数
    23 public static int myNumber;
    24 public static int yourNumber;
    25
    26 static void Main(string[] args)
    27 {
    28 //正确
    29 OutTest(out myNumber, out yourNumber);
    30 Console.WriteLine(string.Format("myNumber = {0}, yourNumber = {1}", myNumber, yourNumber));
    31 RefTest(ref myNumber, ref yourNumber);
    32 Console.WriteLine(string.Format("myNumber = {0}, yourNumber = {1}", myNumber, yourNumber));
    33
    34 //错误
    35 OutTest(out firstNumber, out secondNumber);
    36 Console.WriteLine(string.Format("firstNumber = {0}, secondNumber = {1}", firstNumber, secondNumber));
    37 RefTest(ref firstNumber, ref secondNumber);
    38 Console.WriteLine(string.Format("firstNumber = {0}, secondNumber = {1}", firstNumber, secondNumber));
    45 }
    46 }
    47 }
    48

     


相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载