跳過到頁腳內容
.NET幫助

C# Ref 關鍵字(開發者的工作原理)

C# 關鍵字 ref是每個初學者都應該學習的重要工具。 它用來以參照而非值來傳遞參數,允許在被呼叫的方法內部對參照類型變數所做的變更反映在方法外部。 在本教程中,我們將介紹 ref 關鍵字的細節,並探討能說明其運作方式的各種控制台程式碼範例。

參考關鍵字簡介

在 C# 中傳遞方法參數時,預設是以值來傳送。 這表示會建立一個參數值的複本,在被呼叫的方法中進行的任何變更都不會影響方法外的原始變數。 ref 關鍵字改變了這種行為,讓您可以透過引用傳遞參數。 當參數以參照方式傳遞時,在方法內所做的任何變更都會直接影響方法外的原始變數。

主要概念

  • ref 關鍵字:用於指示變數按引用傳遞。 -引用變數:引用資料儲存的記憶體位置的類型。 -值類型:儲存實際資料的類型。 -原始變數:方法外部的變量,反映在使用 ref 關鍵字時在方法內部所做的變更。

參考傳輸

讓我們先從瞭解變數如何透過參考傳遞的概念開始。 假設您有一個方法可以遞增一個整數,如以下程式碼所示:

class Program
{
    // Method increments the given integer by one
    static void IncrementByOne(int num)
    {
        num++;
    }

    static void Main()
    {
        int value = 5;
        IncrementByOne(value);
        Console.WriteLine(value);  // Output: 5
    }
}
class Program
{
    // Method increments the given integer by one
    static void IncrementByOne(int num)
    {
        num++;
    }

    static void Main()
    {
        int value = 5;
        IncrementByOne(value);
        Console.WriteLine(value);  // Output: 5
    }
}
Friend Class Program
	' Method increments the given integer by one
	Private Shared Sub IncrementByOne(ByVal num As Integer)
		num += 1
	End Sub

	Shared Sub Main()
		Dim value As Integer = 5
		IncrementByOne(value)
		Console.WriteLine(value) ' Output: 5
	End Sub
End Class
$vbLabelText   $csharpLabel

在上面的程式碼中,即使我們在 IncrementByOne 方法中遞增了 num,原始的 value 仍然保持不變。 這是因為 num 是原始變數的副本,對其所做的更改不會影響原始變數。

使用 ref 關鍵字

現在,讓我們看看 ref 關鍵字如何改變這種行為。 透過使用 ref,您可以按引用將變數傳遞給方法,如下面的程式碼範例之一所示。

class Program
{
    // Method increments the given integer by one using ref
    static void IncrementByOneRef(ref int num)
    {
        num++;
    }

    static void Main()
    {
        int value = 5;
        IncrementByOneRef(ref value);
        Console.WriteLine(value);  // Output: 6
    }
}
class Program
{
    // Method increments the given integer by one using ref
    static void IncrementByOneRef(ref int num)
    {
        num++;
    }

    static void Main()
    {
        int value = 5;
        IncrementByOneRef(ref value);
        Console.WriteLine(value);  // Output: 6
    }
}
Friend Class Program
	' Method increments the given integer by one using ref
	Private Shared Sub IncrementByOneRef(ByRef num As Integer)
		num += 1
	End Sub

	Shared Sub Main()
		Dim value As Integer = 5
		IncrementByOneRef(value)
		Console.WriteLine(value) ' Output: 6
	End Sub
End Class
$vbLabelText   $csharpLabel

請注意方法簽章和呼叫中都存在的 ref 關鍵字。 這告訴 C# 你想透過引用傳遞 value 變數。 因此,在 IncrementByOneRef 方法中所做的變更會反映在原始的 value 變數中。

使用值類型工作

當處理整數、雙精確度浮點數和結構體等類型時,關鍵字 ref 特別有用。 這些類型會直接儲存在記憶體中,透過參照來傳遞這些類型可以改善效能,並對資料操作進行更精確的控制。

修改參考變數

雖然 ref 關鍵字通常與值類型相關聯,但它也可以與引用類型變數一起使用。 參考類型,就像類別和陣列一樣,儲存的是對記憶體中實際資料的參考,而不是資料本身。 這表示您要處理的是類似指針的結構,參考傳遞可以產生不同的結果,如以下範例所示:

class Person
{
    public string Name { get; set; }
}

class Program
{
    // Method changes the reference of the person variable to a new Person object
    static void ChangeName(ref Person person)
    {
        person = new Person { Name = "Alice" };
    }

    static void Main()
    {
        Person person = new Person { Name = "Bob" };
        ChangeName(ref person);
        Console.WriteLine(person.Name);  // Output: Alice
    }
}
class Person
{
    public string Name { get; set; }
}

class Program
{
    // Method changes the reference of the person variable to a new Person object
    static void ChangeName(ref Person person)
    {
        person = new Person { Name = "Alice" };
    }

    static void Main()
    {
        Person person = new Person { Name = "Bob" };
        ChangeName(ref person);
        Console.WriteLine(person.Name);  // Output: Alice
    }
}
Friend Class Person
	Public Property Name() As String
End Class

Friend Class Program
	' Method changes the reference of the person variable to a new Person object
	Private Shared Sub ChangeName(ByRef person As Person)
		person = New Person With {.Name = "Alice"}
	End Sub

	Shared Sub Main()
		Dim person As New Person With {.Name = "Bob"}
		ChangeName(person)
		Console.WriteLine(person.Name) ' Output: Alice
	End Sub
End Class
$vbLabelText   $csharpLabel

在這個例子中,ChangeName 方法將 person 變數的引用改為新的 Person 物件。 因此,原來的 person 變數現在指向另一個對象,它的名稱是"Alice"。

使用參照類型參數的方法重載。

您可以有多個名稱相同但參數不同的方法。 這稱為方法重載。 使用 ref 關鍵字時,方法重載會變得更強大。

class Calculator
{
    // Method adds two integers and modifies the first using ref
    public static void Add(ref int x, int y)
    {
        x += y;
    }

    // Method adds two doubles and modifies the first using ref
    public static void Add(ref double x, double y)
    {
        x += y;
    }
}

class Program
{
    static void Main()
    {
        int intValue = 5;
        double doubleValue = 7.5;

        // Call overloaded Add methods with ref parameters
        Calculator.Add(ref intValue, 3);
        Calculator.Add(ref doubleValue, 2.5);

        Console.WriteLine(intValue);      // Output: 8
        Console.WriteLine(doubleValue);   // Output: 10.0
    }
}
class Calculator
{
    // Method adds two integers and modifies the first using ref
    public static void Add(ref int x, int y)
    {
        x += y;
    }

    // Method adds two doubles and modifies the first using ref
    public static void Add(ref double x, double y)
    {
        x += y;
    }
}

class Program
{
    static void Main()
    {
        int intValue = 5;
        double doubleValue = 7.5;

        // Call overloaded Add methods with ref parameters
        Calculator.Add(ref intValue, 3);
        Calculator.Add(ref doubleValue, 2.5);

        Console.WriteLine(intValue);      // Output: 8
        Console.WriteLine(doubleValue);   // Output: 10.0
    }
}
Friend Class Calculator
	' Method adds two integers and modifies the first using ref
	Public Shared Sub Add(ByRef x As Integer, ByVal y As Integer)
		x += y
	End Sub

	' Method adds two doubles and modifies the first using ref
	Public Shared Sub Add(ByRef x As Double, ByVal y As Double)
		x += y
	End Sub
End Class

Friend Class Program
	Shared Sub Main()
		Dim intValue As Integer = 5
		Dim doubleValue As Double = 7.5

		' Call overloaded Add methods with ref parameters
		Calculator.Add(intValue, 3)
		Calculator.Add(doubleValue, 2.5)

		Console.WriteLine(intValue) ' Output: 8
		Console.WriteLine(doubleValue) ' Output: 10.0
	End Sub
End Class
$vbLabelText   $csharpLabel

在上面的例子中,我們重載了 Add 方法,使其能夠同時處理 intdouble 類型。 ref 關鍵字允許這些方法直接修改原始變數。

使用 out 關鍵字

另一個相關的關鍵字是 out。 它與 ref 類似,但用途略有不同。 雖然 ref 要求變數在傳遞之前必須已初始化,但 out 關鍵字用於希望方法為不一定具有初始值的參數賦值的情況:

class Program
{
    // Method computes the quotient and uses the out keyword to return it
    static void Divide(int dividend, int divisor, out int quotient)
    {
        quotient = dividend / divisor;
    }

    static void Main()
    {
        int result;
        Divide(10, 2, out result);
        Console.WriteLine(result);  // Output: 5
    }
}
class Program
{
    // Method computes the quotient and uses the out keyword to return it
    static void Divide(int dividend, int divisor, out int quotient)
    {
        quotient = dividend / divisor;
    }

    static void Main()
    {
        int result;
        Divide(10, 2, out result);
        Console.WriteLine(result);  // Output: 5
    }
}
Friend Class Program
	' Method computes the quotient and uses the out keyword to return it
	Private Shared Sub Divide(ByVal dividend As Integer, ByVal divisor As Integer, ByRef quotient As Integer)
		quotient = dividend \ divisor
	End Sub

	Shared Sub Main()
		Dim result As Integer = Nothing
		Divide(10, 2, result)
		Console.WriteLine(result) ' Output: 5
	End Sub
End Class
$vbLabelText   $csharpLabel

在這個例子中,Divide 方法計算商,並使用 out 關鍵字將其賦值給 quotient 變數。 值得注意的是,在將 result 傳遞給該方法之前,無需對其進行初始化。

關鍵字 ref 與 out 的差異

關鍵字 out 與關鍵字 ref 類似,但有很大不同。 out 參數不需要初始值,而 ref 參數在方法呼叫之前必須具有初始值。

潛在陷阱

雖然 refout 關鍵字是強大的工具,但應該謹慎使用。 錯誤使用這些關鍵字可能會導致混亂的程式碼和意想不到的行為。 例如,你不能在 refout 參數中使用非引用變數而不先對其進行初始化,因為這會導致編譯錯誤。

關鍵字 ref 的進階用法

使用參照類型和值類型工作

在使用 ref 關鍵字時,理解引用類型和值類型之間的差異至關重要。

-引用類型:變數指的是資料儲存在記憶體中的位置,例如物件、陣列等。 -值類型:變數直接包含數據,例如整數、浮點數等。

使用 ref 值類型可以允許變更反映在方法外部,而引用類型變數本身就具有這種行為。

使用 ref 關鍵字的擴充方法

您也可以將 ref 關鍵字與擴充方法一起使用。 舉例說明:

public static class StringExtensions
{
    // Extension method that appends a value to the input string
    public static void AppendValue(ref this string input, string value)
    {
        input += value;
    }
}
public static class StringExtensions
{
    // Extension method that appends a value to the input string
    public static void AppendValue(ref this string input, string value)
    {
        input += value;
    }
}
Public Module StringExtensions
	' Extension method that appends a value to the input string
	Public Sub AppendValue(ByRef Me input As String, ByVal value As String)
		input &= value
	End Sub
End Module
$vbLabelText   $csharpLabel

編譯器錯誤與 ref 關鍵字

如果在方法簽章或方法呼叫中忘記包含 ref 關鍵字,則在編譯時會導致編譯器錯誤。

Async 方法與引用參數

請注意,您不能將 ref 參數與迭代器方法或 async 方法一起使用,因為這些方法需要按值傳遞參數。

介紹 Iron Suite

除了理解 C# 中的 ref 關鍵字等關鍵概念之外,還有一系列強大的工具可以大大簡化開發人員的工作。 Iron Suite 是一系列強大的工具和程式庫,包括 IronPDF、IronXL、IronOCR 和 IronBarcode。 讓我們一起探索這些工具,看看它們如何在沒有任何爭議的情況下提升您的編碼經驗。

IronPDF PDF 處理變得簡單

瞭解 IronPDF 是 Iron Suite 的重要組成部分。它是一個可以讓開發人員在 C# 中建立、讀取和編輯 PDF 檔案的函式庫。 如果您想將 HTML 轉換成 PDF,IronPDF 有您需要的工具。 查看將 HTML 轉換為 PDF 的教學,瞭解更多關於此功能功能的資訊。

指尖上的 IronXL.Excel 操作。

在 C# 中處理 Excel 檔案可能具有挑戰性,但IronXL 的功能簡化了這項工作。 它能讓您在沒有安裝 Excel 的情況下讀取、寫入、編輯和處理 Excel 檔案。 從匯入資料到建立新的試算表,IronXL.Excel 都能讓您用 C# 來處理 Excel。

IronOCR C# 光學字元識別

光學字元識別 (OCR) 可能很複雜,但發現 IronOCR 可簡化流程。 使用這個函式庫,您可以讀取影像中的文字,並將其轉換為機器可讀的文字。 無論您是需要從掃描的文件中抽取文字,或是從影像中辨識字元,IronOcr 的功能都可以幫到您。

IronBarcode 條碼產生與讀取

BarCode 常用於各行各業,透過 IronBarcode 函式庫,在您的應用程式中處理條碼變得更容易。 這個函式庫可讓您在 C# 中建立、讀取及處理條碼。 IronBarcode 支援多種 QR 和 BarCode 格式。

Iron Suite 如何與 ref 關鍵字相關聯

您可能想知道這些工具與我們討論過的 ref 關鍵字有何關係。 在處理涉及 PDF、Excel、OCR 或條碼的複雜專案時,有效使用 ref 關鍵字和其他 C# 原則對於高效管理程式碼至關重要。

例如,在使用 IronXL 處理大型 Excel 檔案時,使用 ref 關鍵字按引用傳遞物件可以使您的程式碼更有效率、更易於維護。 同樣,使用 IronPDF 處理 PDF 文件時,可能會涉及到 ref 關鍵字發揮作用的方法。

了解核心語言特性(例如 ref 關鍵字)並能使用 Iron Suite 等工具,可以讓你擁有強大的組合能力來建立高效、穩健和多功能的應用程式。 Iron Suite 旨在與您現有的 C# 知識無縫配合,共同協助您建立更專業、更精密的解決方案。

結論

C# 語言具有 ref 關鍵字等特性,為開發人員提供了強大的功能。 結合 Iron Suite,包括 IronPDF、IronXL、IronOCR 和 IronBarcode,可能性變得更加廣泛。

Iron Suite 的每項產品都提供 免費試用,讓您可以探索並使用廣泛的功能,而無需立即投資。 如果您決定購買完整許可證,單一元件的定價從 $999 起。

如果您覺得整套 Iron Suite 符合您的需求,我們將為您提供超值優惠。 您只需支付兩個單獨元件的費用,即可獲得完整的套件。

常見問題解答

我如何在項目中有效地使用 C# ref 關鍵字?

C# ref 關鍵字可以用來傳遞引用參數,允許方法中的更改影響原始變量。這在您需要修改原始資料時特別有用,例如更新對象的屬性或遞增數值。

有哪些情境下 C# ref 關鍵字可以優化性能?

在涉及大量資料處理的情況下使用 ref 關鍵字可以優化性能,因為它允許方法直接對原始資料進行操作而不需要創建副本。這種效率在處理複雜的資料處理任務時尤為重要。

ref 關鍵字與 C# 中的 out 關鍵字有何不同?

ref 關鍵字要求在傳遞給方法之前,變量必須初始化,並允許方法修改其值。相比之下,out 關鍵字不要求在傳遞之前初始化,因為方法會為其賦予新值。

ref 關鍵字可以與 C# 的非同步方法一起使用嗎?

不,ref 關鍵字不能與 C# 的非同步方法一起使用。非同步方法需要通過值傳遞參數,使用 ref 將違背這一要求,導致編譯錯誤。

使用 ref 關鍵字的潛在陷阱是什麼?

潛在的陷阱包括如果錯誤使用 ref 會造成令人困惑的代碼和意外行為。務必確保變量在使用 ref 傳遞之前正確初始化以避免運行時錯誤。

理解 ref 關鍵字對 C# 開發者有什麼好處?

理解 ref 關鍵字對 C# 開發者至關重要,因為它允許更高效的內存管理和資料操作。它還提高了編寫可維護和高效代碼的能力,特別是在處理複雜資料結構時。

有哪些高級工具可以補充 C# ref 在應用開發中的使用?

高級工具如 IronPDF、IronXL、IronOCR 和 IronBarcode 可以補充 ref 關鍵字的使用,通過提供專門用於 PDF 處理、Excel 操作、光學字符識別和條碼操作的功能,增強整體 C# 應用開發。

方法重載如何在 C# 中與 ref 關鍵字一起工作?

C# 中的方法重載允許多個方法具有相同的名稱但不同的參數。當與 ref 關鍵字結合時,它使這些方法可以直接修改原始變量,提供了在重載方法中操縱資料的強大方法。

Jacob Mellor, Team Iron 首席技術官
首席技術官

Jacob Mellor是Iron Software的首席技術官,也是開創C# PDF技術的前瞻性工程師。作為Iron Software核心代碼庫的原始開發者,他自公司成立以來就塑造了公司的產品架構,並與CEO Cameron Rimington將公司轉型為服務NASA、Tesla以及全球政府機構的50多人公司。

Jacob擁有曼徹斯特大學土木工程一級榮譽學士學位(1998年–2001年)。他於1999年在倫敦開立首家軟體公司,並於2005年建立了他的第一個.NET組件,專注於解決Microsoft生態系統中的複雜問題。

他的旗艦作品IronPDF和Iron Suite .NET程式庫全球已獲得超過3000萬次NuGet安裝,他的基礎代碼不斷在全球各地驅動開發者工具。擁有25年以上的商業經驗和41年的編碼專業知識,Jacob仍然專注於推動企業級C#、Java和Python PDF技術的創新,同時指導下一代技術領導者。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我