跳過到頁腳內容
.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 方法中使用 ref 參數,因為這些方法需要以值傳遞參數。

介紹 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 或 BarCode 的複雜專案時,有效使用 ref 關鍵字及其他 C# 原則對於有效管理您的程式碼至關重要。

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

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

結論

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

Iron Suite 的每項產品都提供 免費試用,讓您可以探索並使用廣泛的功能,而無需立即投資。 如果您決定繼續使用完整授權,個別元件的價格將從 $799 起。

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

常見問題解答

如何在專案中有效地使用 C# ref 關鍵字?

C# ref 關鍵字可用於以參照方式傳遞參數,允許在方法中所做的變更影響原始變數。當您需要修改原始資料(例如更新物件的屬性或遞增值)時,此功能尤其有用。

C# ref 關鍵字可以在哪些情況下優化效能?

使用 ref 關鍵字可以優化涉及大型資料處理的場景的效能,因為它允許方法直接在原始資料上操作,而不需要複製。這種效率在處理複雜的資料處理任務時非常重要。

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

ref 關鍵字要求變數在傳給方法之前先初始化,允許方法修改其值。相反,out 關鍵字則不需要在傳送前初始化,因為方法會為它指定新的值。

C# 中的 async 方法可以使用 ref 關鍵字嗎?

在 C# 中,ref 關鍵字不能與 async 方法一起使用。Async 方法要求參數以值傳遞,而使用 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 一起將其轉變為一家擁有超過 50 名員工的公司,為 NASA、特斯拉 和 全世界政府機構服務。

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

他的旗艦產品 IronPDF & Iron Suite .NET 庫在全球 NuGet 被安裝超過 3000 萬次,其基礎代碼繼續為世界各地的開發工具提供動力。擁有 25 年的商業經驗和 41 年的編碼專業知識,Jacob 仍專注於推動企業級 C#、Java 及 Python PDF 技術的創新,同時指導新一代技術領袖。