在 C# 中按引用傳遞物件

Muhammad Maisam Abbas 2024年2月16日
  1. 通過值將變數傳遞給 C# 中的函式
  2. 通過引用將變數傳遞給 C# 中的函式
  3. 通過引用將物件傳遞給 C# 中的函式
在 C# 中按引用傳遞物件

本教程將討論在 C# 中將物件傳遞給函式的方法。

通過值將變數傳遞給 C# 中的函式

預設情況下,在 C# 中,所有值型別變數都是按值傳遞。假設我們按值將變數傳遞給函式,然後在函式中修改該變數。在這種情況下,對函式引數中傳遞的變數的值沒有影響。此處發生的是在記憶體中建立了所傳遞變數的單獨副本,並且所有操作都在該特定副本上執行。以下程式碼示例向我們展示瞭如何在 C# 中按值傳遞值型別變數。

using System;

namespace pass_object_by_reference {
  class Program {
    static void method1(string value) {
      value = "something";
      Console.WriteLine("New value = {0}", value);
    }

    static void Main(string[] args) {
      string valueType = "Nothing";
      method1(valueType);
      Console.WriteLine("Original Value = {0}", valueType);
    }
  }
}

輸出:

New value = something
Original Value = Nothing

在上面的程式碼中,我們按值將字串變數 valueType 傳遞給了 method1() 函式,該函式為傳遞的變數分配了一個新值。當我們按值將 valueType 變數傳遞給 method1() 函式時,會在記憶體中建立具有相同值的變數的兩個不同副本。然後,將變數的第二個副本修改為某物值。該第二個副本只能在 method1() 函式內部訪問。對第二個值的任何更改都不會更改原始變數 valueType

通過引用將變數傳遞給 C# 中的函式

我們還可以在 C# 中使用 ref 關鍵字通過引用傳遞值型別變數。ref 關鍵字指定將值通過引用傳遞到函式。通過這種方法,記憶體中將僅存在變數的一個副本,並且會將單獨的指標傳遞給指向變數值的函式。以下程式碼示例向我們展示瞭如何使用 C# 中的 ref 關鍵字通過引用傳遞值型別變數。

using System;

namespace pass_object_by_reference {
  class Program {
    static void method1(ref string value) {
      value = "something";
      Console.WriteLine("New value = {0}", value);
    }

    static void Main(string[] args) {
      string valueType = "Nothing";
      method1(ref valueType);
      Console.WriteLine("Original Value = {0}", valueType);
    }
  }
}

輸出:

New value = something
Original Value = something

在上面的程式碼中,我們使用 C# 中的 ref 關鍵字通過對 method1() 函式的引用來傳遞值型別變數 valueTypemethod1() 函式將對 valueType 變數的引用作為引數,並將 valueType 變數的值修改為 something。這次,原始值被修改。

通過引用將物件傳遞給 C# 中的函式

預設情況下,所有引用型別變數(例如類例項,結構例項等)都通過引用傳遞到 C# 中的函式。這裡發生的事情是原始物件永遠不會作為引數傳遞給函式。對物件的新引用通過值作為函式的引數傳遞。因此,我們最終有兩個指向相同記憶體位置的指標副本。如果我們修改該指標的值,原始物件的值也會被修改。以下程式碼示例向我們展示瞭如何通過引用 C# 中的函式來傳遞物件。

using System;

namespace pass_object_by_reference {
  public class Sample {
    public string s { get; set; }
  }
  class Program {
    static void dosomething(Sample obj) {
      obj.s = "something";
    }
    static void Main(string[] args) {
      Sample sam = new Sample();
      sam.s = "Nothing";
      dosomething(sam);
      Console.WriteLine(sam.s);
    }
  }
}

輸出:

something

在上面的程式碼中,我們通過引用 dosomething() 函式傳遞了物件 sam,該函式修改了 sam 物件內部的 s 屬性。它將更改原始 sam 物件的值,並將 something 分配給 sam.s 屬性。儘管這是通過引用傳遞物件的預設方法,但是這種方法有一個例外。如果我們使用 new 關鍵字和類建構函式初始化傳遞的物件,則會在記憶體中建立該物件的單獨副本。該物件的值的任何更改都不會更改作為引數傳遞的原始物件。下面的程式碼示例演示一種方案,其中該物件按值傳遞給 C# 中的函式。

using System;

namespace pass_object_by_reference {
  public class Sample {
    public string s { get; set; }
  }
  class Program {
    static void dosomething(Sample obj) {
      Console.WriteLine("Initial passed value = {0}", obj.s);
      obj = new Sample();
      obj.s = "something";
      Console.WriteLine("New value = {0}", obj.s);
    }
    static void Main(string[] args) {
      Sample sam = new Sample();
      sam.s = "Nothing";
      dosomething(sam);
      Console.WriteLine("Original Value = {0}", sam.s);
    }
  }
}

輸出:

Initial passed value = Nothing
New value = something
Original Value = Nothing

在上面的程式碼中,我們按值將物件 sam 傳遞給了 C# 中的 dosomething() 函式。dosomething() 函式接受引數,列印其初始值,修改值,並列印修改後的值。該新值分配給新的儲存位置,原始物件 sam 無法訪問。

Muhammad Maisam Abbas avatar Muhammad Maisam Abbas avatar

Maisam is a highly skilled and motivated Data Scientist. He has over 4 years of experience with Python programming language. He loves solving complex problems and sharing his results on the internet.

LinkedIn

相關文章 - Csharp Class