歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C#中應用參數ref 和 輸出參數out

C#中應用參數ref 和 輸出參數out

日期:2017/3/1 10:45:32   编辑:Linux編程

從CLR的角度看,關鍵字out和關鍵字ref是等效的,這就是說,無論使用哪個關鍵字,都會生成相同的元數據和IL代碼。但是,C#編譯器將兩個關鍵字區別對待,在C#中,這兩個關鍵字的區別在於哪個方法負責初始化引用對象。如果方法的參數標記為out,那麼調用者不希望在調用方法之前初始化對象,被調用的方法不能讀取對象的值,而且被調用的方法必須在返回之前為對象賦值。如果方法的參數標記為ref,那麼調用者必須在調用方法之前首先初始化參數的值,被調用的方法可以讀取參數或為參數賦值。

  1. namespace 方法參數
  2. {
  3. /// <summary>
  4. /// 參數測試
  5. /// </summary>
  6. class Program
  7. {
  8. static void Main(string[] args)
  9. {
  10. //輸出參數
  11. Point p = new Point(10, 12);
  12. int x, y;//輸出參數不需要賦初值//與引用類型相似,輸出參數也不開辟新的內存區域,
  13. 但在調用方法前無需對變量進行初始化。
  14. p.GetPoint(out x, out y);
  15. Console.WriteLine("p({0},{1})", x, y);
  16. //引用參數
  17. Point2 p1 = new Point2(12, 23);
  18. int x1 = 0, y1 = 0;//引用參數一定要賦初值
  19. p1.GetPoint(ref x1, ref y1);
  20. Console.WriteLine("p1({0},{1})", x1, y1);
  21. // 參數數組
  22. int[] a = { 1, 2, 3, 4, 5 };
  23. Array.F(a);
  24. Array.F(10, 20, 30, 60, 50);//F(new int[] {10, 20, 30, 60, 50})
  25. Array.F();
  26. Console.ReadLine();
  27. }
  28. }
  29. /// <summary>
  30. /// 輸出參數可返回多個值
  31. /// </summary>
  32. class Point
  33. {
  34. int X, Y;
  35. public Point(int x, int y)
  36. {
  37. this.X = x;
  38. this.Y = y;
  39. }
  40. public void GetPoint(out int x, out int y)//輸出參數用於傳遞方法返回的數據。out修飾符後應跟與形參類型相同的類型申明。在方法返回後,傳遞的變量被認為經過了初始化。
  41. {
  42. y = this.Y;
  43. x = this.X;
  44. }
  45. }
  46. /// <summary>
  47. /// 引用參數
  48. /// </summary>
  49. class Point2
  50. {
  51. int X, Y;
  52. public Point2(int x, int y)
  53. {
  54. this.X = x;
  55. this.Y = y;
  56. }
  57. public void GetPoint(ref int x, ref int y)
  58. {
  59. y = this.Y;
  60. x = this.X;
  61. }
  62. }
  63. /// <summary>
  64. /// 參數數組
  65. /// </summary>
  66. class Array
  67. {
  68. public static void F(params int[] args)
  69. {
  70. Console.WriteLine("數組長度為:{0}", args.Length);
  71. foreach (int i in args)
  72. {
  73. Console.WriteLine("{0}", i);
  74. }
  75. Console.WriteLine();
  76. }
  77. }
  78. }

out parameter modifier (C# Reference)

The out keyword causes arguments to be passed by reference. This is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. For example:

C#
class OutExample { static void Method(out int i) { i = 44; } static void Main() { int value; Method(out value); // value is now 44 } } 

Although variables passed as out arguments do not have to be initialized before being passed, the called method is required to assign a value before the method returns.

Although the ref and out keywords cause different run-time behavior, they are not considered part of the method signature at compile time. Therefore, methods cannot be overloaded if the only difference is that one method takes a ref argument and the other takes an out argument. The following code, for example, will not compile:

C#
class CS0663_Example { // Compiler error CS0663: "Cannot define overloaded  // methods that differ only on ref and out". public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } } 

Overloading can be done, however, if one method takes a ref or out argument and the other uses neither, like this:

C#
class OutOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(out int i) { i = 5; } } 

Properties are not variables and therefore cannot be passed as out parameters.

For information about passing arrays, see Passing Arrays Using ref and out (C# Programming Guide).

Example

Declaring an out method is useful when you want a method to return multiple values. The following example uses out to return three variables with a single method call. Note that the third argument is assigned to null. This enables methods to return values optionally.

C#
 class OutReturnExample { static void Method(out int i, out string s1, out string s2) { i = 44; s1 = "I've been returned"; s2 = null; } static void Main() { int value; string str1, str2; Method(out value, out str1, out str2); // value is now 44 // str1 is now "I've been returned" // str2 is (still) null; } }

ref(C# 參考)

ref 關鍵字使參數按引用傳遞。 其效果是,當控制權傳遞回調用方法時,在方法中對參數的任何更改都將反映在該變量中。

注意

不要將“通過引用傳遞”概念與“引用類型”概念相混淆。 這兩個概念不同。 方法參數無論是值類型還是引用類型,都可通過 ref 進行修飾。 通過引用傳遞值類型時沒有值類型裝箱。

若要使用 ref 參數,則方法定義和調用方法都必須顯式使用 ref 關鍵字。 例如:

C#
 class RefExample { static void Method(ref int i) { // Rest the mouse pointer over i to verify that it is an int. // The following statement would cause a compiler error if i // were boxed as an object. i = i + 44; } static void Main() { int val = 1; Method(ref val); Console.WriteLine(val); // Output: 45 } }

傳遞到 ref 參數的參數必須最先初始化。 這與 out 不同,後者的參數在傳遞之前不需要顯式初始化。 有關更多信息,請參見 out。

盡管 ref 和 out 關鍵字會導致不同的運行時行為,但在編譯時並不會將它們視為方法簽名的一部分。 因此,如果兩個方法唯一的區別是:一個接受 ref 參數,另一個接受 out 參數,則無法重載這兩個方法。 例如,不會編譯下面的代碼:

C#
class CS0663_Example { // Compiler error CS0663: "Cannot define overloaded  // methods that differ only on ref and out". public void SampleMethod(out int i) { } public void SampleMethod(ref int i) { } }

但是,如果一個方法采用 ref 或 out 參數,而另一個方法不采用這兩個參數,則可以進行重載,如下例所示:

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

屬性不是變量。 它們實際上是方法,因此不能作為 ref 參數進行傳遞。

有關如何傳遞數組的信息,請參見使用 ref 和 out 傳遞數組(C# 編程指南)。

示例

按引用傳遞值類型(如本主題前面所示)是有用的,但是 ref 對於傳遞引用類型也是很有用的。 這允許被調用的方法修改該引用所引用的對象,因為引用本身是按引用來傳遞的。 下面的示例顯示出當引用類型作為 ref 參數傳遞時,可以更改對象本身。 有關更多信息,請參見 傳遞引用類型參數(C# 編程指南)。

C#
class RefExample2 { static void Method(ref string s) { s = "changed"; } static void Main() { string str = "original"; Method(ref str); Console.WriteLine(str); } } // Output: changed
Copyright © Linux教程網 All Rights Reserved