Programming C#.Classes and Objects.传递参数

ref 关键字通过引用(而非值)传递参数。 通过引用传递的效果是,对所调用方法中的参数进行的任何更改都反映在调用方法中。

说明:
不要混淆通过引用传递的概念与引用类型的概念。 这两种概念是不同的。 无论方法参数是值类型还是引用类型,均可由 ref 修改。 当通过引用传递时,不会对值类型装箱。

若要使用 ref 参数,方法定义和调用方法均必须显式使用 ref 关键字,如下面的示例所示。

 1 class RefExample
 2     {
 3         static void Method(ref int i)
 4         {
 5             // Rest the mouse pointer over i to verify that it is an int.
 6             // The following statement would cause a compiler error if i
 7             // were boxed as an object.
 8             i = i + 44;
 9         }
10 
11         static void Main()
12         {
13             int val = 1;
14             Method(ref val);
15             Console.WriteLine(val);
16 
17             // Output: 45
18         }
19     }

传递到 ref 形参的实参必须先经过初始化,然后才能传递。 这与 out 形参不同,在传递之前,不需要显式初始化该形参的实参。

类的成员不能具有仅在 ref 和 out 方面不同的签名。 如果类型的两个成员之间的唯一区别在于其中一个具有 ref 参数,而另一个具有 out 参数,则会发生编译错误。 例如,以下代码将不会编译。

1 class CS0663_Example
2 {
3     // Compiler error CS0663: "Cannot define overloaded 
4     // methods that differ only on ref and out".
5     public void SampleMethod(out int i) { }
6     public void SampleMethod(ref int i) { }
7 }

但是,当一个方法具有 ref 或 out 参数,另一个方法具有值参数时,则可以完成重载,如下面的示例所示。

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

你不能将 ref 和 out 关键字用于以下几种方法:

  • 异步方法,通过使用 async 修饰符定义。

  • 迭代器方法,包括 yield return 或 yield break 语句。

还可以使用 ref 关键字传递引用类型:

 1 class RefExample2
 2 {
 3     static void ChangeByReference(ref Product itemRef)
 4     {
 5         // The following line changes the address that is stored in  
 6         // parameter itemRef. Because itemRef is a ref parameter, the
 7         // address that is stored in variable item in Main also is changed.
 8         itemRef = new Product("Stapler", 99999);
 9 
10         // You can change the value of one of the properties of
11         // itemRef. The change happens to item in Main as well.
12         itemRef.ItemID = 12345;
13     }
14 
15     static void Main()
16     {
17         // Declare an instance of Product and display its initial values.
18         Product item = new Product("Fasteners", 54321);
19         System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}
",
20             item.ItemName, item.ItemID);
21 
22         // Send item to ChangeByReference as a ref argument.
23         ChangeByReference(ref item);
24         System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}
",
25             item.ItemName, item.ItemID);
26     }
27 }
28 
29 class Product
30 {
31     public Product(string name, int newID)
32     {
33         ItemName = name;
34         ItemID = newID;
35     }
36 
37     public string ItemName { get; set; }
38     public int ItemID { get; set; }
39 }
40 
41 // Output: 
42 //Original values in Main.  Name: Fasteners, ID: 54321
43 
44 //Back in Main.  Name: Stapler, ID: 12345
View Code

 out 关键字会导致参数通过引用来传递。 这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化。 若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字。尽管作为 out 参数传递的变量不必在传递之前进行初始化,但被调用的方法必须在返回之前赋一个值。

原文地址:https://www.cnblogs.com/stemon/p/4088201.html