C# 中 ref、out 和 in 關鍵字的用法是什麼?

WBOY
發布: 2023-09-18 12:45:03
轉載
856 人瀏覽過

C# 中 ref、out 和 in 关键字的用法是什么?

在C#中,大多數方法可以具有零個或多個參數,這些參數定義了必須提供給方法的資料。調用方法的任何程式碼都必須將資料(稱為參數)傳遞給該方法。方法將其輸入聲明為參數,並且它們由呼叫代碼以參數的形式提供。

例如,考慮以下方法和隨後的方法呼叫。

static void Greet(string greeting){
   Console.WriteLine(greeting);
}
...
Greet("Hello");
登入後複製

在上面的範例中,greeting是Greet()方法的參數,而"Hello"是傳遞給該方法的參數。

當呼叫一個方法並傳遞參數時,它們是按值傳遞的,這意味著在傳遞給方法時會建立一個值的副本。在方法內部對參數所做的任何更改都不會反映在原始變數上。

using System;
int number = 8;
Increase(number);
Console.WriteLine(number); // prints 8
static void Increase(int num){
   num = num + 1;
   Console.WriteLine(num); // prints 9
}
登入後複製

當您傳遞引用類型變數(例如物件)時,C# 仍然會按值複製引用,因為該變數保存的是引用,而不是實際的物件。因此,即使傳遞了引用變數的副本,它們也都引用了記憶體中的同一個物件。因此,方法內部的變數對物件所做的任何更改對於方法外部的變數都是可見的。

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
Promote(john);
Console.WriteLine(john.Salary); // prints 60000
static void Promote(User u){
   u.Salary += 10000;
   Console.WriteLine(u.Salary); // prints 60000
}
登入後複製

但是,如果您在方法內部變更變數的值本身,則該變更不會反映在方法外部,因為僅變更了副本,而不是實際物件。例如,我們可以在方法內部將參數賦值為null,而實際變數將保持不變。

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
Promote(john);
Console.WriteLine(john.Salary); // prints 50000
static void Promote(User u){
   u = null;
}
登入後複製

C#允許使用三個不同的修飾符關鍵字來控制方法的參數。

ref修飾符

C#允許您使用ref#修飾符透過引用傳遞參數。無論要傳遞的變數屬於引用類型還是值類型,都不重要。參數和參數將引用相同的記憶體位置。

在下面的範例中,將參數u設為null也將使john變數為null,從而引發空引用異常。

範例

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
Promote(ref john);
Console.WriteLine(john.Salary); // throws System.NullReferenceException
static void Promote(ref User u){
   u = null;
}
登入後複製

使用ref修飾符傳遞的參數必須在傳遞之前進行初始化。

out修飾符

它與ref修飾符類似,除了:

  • 參數在進入函數之前不需要進行初始化

  • #參數在從函數中出來之前必須進行初始化(賦值)

#在下面的範例中,Hire函數透過out修飾符初始化了一個傳遞給它的新使用者物件。請注意,在呼叫Hire方法時,變數john是即時宣告的。

using System;
Hire(out User john);
Console.WriteLine(john.Salary); // prints 50000
static void Hire(out User u){
   u = new User{
      Name = "John",
      Salary = 50000
   };
}
登入後複製

ref修飾符一樣,由out修飾符標記的變數透過引用傳遞。

通常是out > 變數用於從函數取得多個返回值,如下-

using System;
var john = new User{
   Name = "John",
   Salary = 50000
};
bool shouldPromote = Raise(john.Salary, out double hike);
Console.WriteLine(shouldPromote); // True
Console.WriteLine($"Hike Amount = {hike}"); // prints 5000
static bool Raise(int salary, out double hike){
   hike = salary * 0.1;
   return hike < 7000;
}
登入後複製

in修飾符

它類似於refout參數,但不同的是接受in參數的方法不能修改該參數的值。如果嘗試修改,C#編譯器會產生編譯時錯誤。

in參數可以避免將大型值類型的記憶體複製到參數變數中,同時防止物件被意外修改。這在將大型值類型傳遞給方法時非常有用。

var point = new Coord();
Verify(point);
static void Verify(in Coord c){
   // error: Cannot assign to variable &#39;in Coord&#39; because it is a readonly variable
   c = new Coord();
}
struct Coord{
   public int X;
   public int Y;
}
登入後複製

範例

 即時示範

using System;
class Program{
   static void Main(){
      int number = 8;
      Increase(number);
      Console.WriteLine(number); // prints 8
      var john = new User { Name = "John", Salary = 50000 };
      Promote(john);
      Console.WriteLine(john.Salary); // prints 60000
      Leave(john);
      Console.WriteLine(john.Salary); // prints 60000

      LeaveByRef(ref john);
      Console.WriteLine(john?.Salary); // prints nothing

      User dave;
      Hire(out dave);
      Console.WriteLine(dave.Salary); // prints 50000
   }
   static void Increase(int num){
      num = num + 1;
      Console.WriteLine(num); // prints 9
   }
   static void Promote(User u){
      u.Salary += 10000;
      Console.WriteLine(u.Salary); // prints 60000
   }
   static void Leave(User u){
      u = null;
   }
   static void LeaveByRef(ref User u){
      u = null;
   }
   static void Hire(out User u){
      u = new User{
         Name = "John",
         Salary = 50000
      };  
   }
}
class User{
   public string Name { get; set; }
   public int Salary { get; set; }
}
登入後複製

輸出

9
8
60000
60000
60000
50000
登入後複製

以上是C# 中 ref、out 和 in 關鍵字的用法是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:tutorialspoint.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板