c# ref out 區別 比較 彙總
ref(C# 參考)
ref 關鍵字會導致引數通過引用傳遞,而不是通過值傳遞。 通過引用傳遞的效果是,對所呼叫方法中的引數進行的任何更改都反映在呼叫方法中。 例如,如果呼叫方傳遞本地變數表示式或陣列元素訪問表示式,所呼叫方法會將物件替換為 ref 引數引用的物件,然後呼叫方的本地變數或陣列元素將開始引用新物件。
注意 |
---|
不要混淆通過引用傳遞的概念與引用型別的概念。 這兩種概念是不同的。 無論方法引數是值型別還是引用型別,均可由 ref 修改。 當通過引用傳遞時,不會對值型別裝箱。 |
若要使用 ref 引數,方法定義和呼叫方法均必須顯式使用 ref 關鍵字,如下面的示例所示。
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 引數,則會發生編譯錯誤。 例如,以下程式碼將不會編譯。
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 引數,另一個方法具有值引數時,則可以完成過載,如下面的示例所示。
class RefOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(ref int i) { } }
在其他要求籤名匹配的情況下(如隱藏或重寫),ref 和 out 是簽名的一部分,相互之間不匹配。
屬性不是變數。 它們是方法,不能傳遞到 ref 引數。
有關如何傳遞陣列的資訊,請參閱使用 ref 和 out 傳遞陣列(C# 程式設計指南)。
你不能將 ref 和 out 關鍵字用於以下幾種方法:
-
非同步方法,通過使用 async 修飾符定義。
-
迭代器方法,包括 yield return 或 yield break 語句。
示例
前面的示例演示當通過引用傳遞值型別時會發生什麼情況。 你還可以使用 ref 關鍵字傳遞引用型別。 通過引用傳遞引用型別可以使所呼叫方法將呼叫方法中的物件替換為引用引數所引用的物件。 物件的儲存位置按引用引數的值傳遞到方法。 如果更改引數儲存位置中的值(以指向新物件),你還可以將儲存位置更改為呼叫方所引用的位置。 下面的示例將引用型別的例項作為 ref 引數傳遞。 有關如何通過值和引用傳遞引用型別的詳細資訊,請參閱傳遞引用型別引數(C# 程式設計指南)。
class RefExample2 { static void ChangeByReference(ref Product itemRef) { // The following line changes the address that is stored in // parameter itemRef. Because itemRef is a ref parameter, the // address that is stored in variable item in Main also is changed. itemRef = new Product("Stapler", 99999); // You can change the value of one of the properties of // itemRef. The change happens to item in Main as well. itemRef.ItemID = 12345; } static void Main() { // Declare an instance of Product and display its initial values. Product item = new Product("Fasteners", 54321); System.Console.WriteLine("Original values in Main. Name: {0}, ID: {1}\n", item.ItemName, item.ItemID); // Send item to ChangeByReference as a ref argument. ChangeByReference(ref item); System.Console.WriteLine("Back in Main. Name: {0}, ID: {1}\n", item.ItemName, item.ItemID); } } class Product { public Product(string name, int newID) { ItemName = name; ItemID = newID; } public string ItemName { get; set; } public int ItemID { get; set; } } // Output: //Original values in Main. Name: Fasteners, ID: 54321 //Back in Main. Name: Stapler, ID: 12345
out(C# 參考)
你可以在兩個上下文(每個都是指向詳細資訊的連結)中使用 out 上下文關鍵字作為引數修飾符,或在介面和委託中使用泛型型別引數宣告。本主題討論引數修飾符,但你可以參閱其他主題瞭解關於泛型型別引數宣告的資訊。
out 關鍵字通過引用傳遞引數。這與 ref 關鍵字相似,只不過 ref 要求在傳遞之前初始化變數。若要使用 out 引數,方法定義和呼叫方法均必須顯式使用 out 關鍵字。例如:
class OutExample { static void Method(out int i) { i = 44; } static void Main() { int value; Method(out value); // value is now 44 } }
儘管作為 out 引數傳遞的變數無需在傳遞之前初始化,呼叫方法仍要求在方法返回之前賦值。
儘管 ref 和 out 關鍵字會導致不同的執行時行為,它們並不被視為編譯時方法簽名的一部分。因此,如果唯一的不同是一個方法採用 ref 引數,而另一個方法採用 out 引數,則無法過載這兩個方法。例如,以下程式碼將不會編譯:
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 引數,而另一個方法採用其他引數,則可以完成過載,如:
class OutOverloadExample { public void SampleMethod(int i) { } public void SampleMethod(out int i) { i = 5; } }
屬性不是變數,因此不能作為 out 引數傳遞。
有關傳遞陣列的資訊,請參閱使用 ref 和 out 傳遞陣列(C# 程式設計指南)。
你不能將 ref 和 out 關鍵字用於以下幾種方法:
非同步方法,通過使用 async 修飾符定義。
迭代器方法,包括 yield return 或 yield break 語句。
如果希望方法返回多個值,可以宣告 out 方法。下面的示例使用 out 返回具有單個方法呼叫的三個變數。注意,第三個引數賦 null 值。這使得方法可以有選擇地返回值。
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; } } 參閱: https://msdn.microsoft.com/zh-cn/library/t3c3bfhx.aspx https://msdn.microsoft.com/zh-cn/library/14akc2c7.aspx
相關文章
- C#中ref和out的區別C#
- ref和out區別
- ref和out的區別
- NET|Ref 和out 的區別和聯絡
- 圖解C#的值型別,引用型別,棧,堆,ref,out圖解C#型別
- out關鍵字和ref關鍵字的區別
- 全面分析C#方法中的ref和outC#
- c#.net中引數修飾符ref,out ,params得區別C#
- c#基礎系列3—深入理解ref 和outC#
- C# 物件比較(值型別、引用型別)C#物件型別
- C#中ref、out及特殊說明引數的用法C#
- [JavaWeb]SpringMVC與Struts2區別與比較總結JavaWebSpringMVC
- C#中的ref和out的意義和使用方法C#
- Spring中ref local=""與ref bean=""的區別SpringBean
- C# DataRow 比較C#
- out,ref,params引數傳遞
- Rust 中 *、&、mut、&mut、ref、ref mut 的用法和區別Rust
- RabbitMq、ActiveMq、ZeroMq、kafka之間的比較,資料彙總MQKafka
- Vue和微信小程式的區別、比較Vue微信小程式
- Hibernate和Ibatis區別和比較BAT
- Vue 中ref()與 reactive() 的區別VueReact
- Linux常見問題彙總,比較適合菜鳥哈Linux
- Spring和SpringBoot比較,解惑區別Spring Boot
- Java:比較運算子compareTo()、equals()、==之間的區別與應用總結Java
- 訂單量多,用什麼智慧軟體彙總比較好
- 【彙總】學習Python用哪個直譯器比較好?Python
- Oracle date 型別比較和String比較Oracle型別
- JAVA中字串比較equals()和equalsIgnoreCase()的區別Java字串
- Go與C#的比較 - RedditGoC#
- C#比較dynamic和Dictionary效能C#
- c# 方法引數(傳值,傳引用,ref,out,params,可選引數,命名引數)C#
- C#知識大彙總C#
- C#中DllImport用法彙總C#Import
- Prometheus thanos Victoriametrics比較 victoria prometheus 區別 轉載Prometheus
- php型別比較表PHP型別
- Java Integer型別比較Java型別
- C# 中 Struct 和 Class 的區別總結C#Struct
- 認真總結Vue3中ref與reactive區別和isRef與isReactive 型別判斷VueReact型別