在 C# 中按引用傳遞物件

Muhammad Maisam Abbas 2023年1月30日 2021年4月29日
  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