首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# ref 與 out 關鍵字差異總結:傳址 vs 輸出參數

     編輯:關於C#

核心差異速查

特性refout
呼叫前是否需初始化✅ 必須已賦值❌ 不需初始化
方法內是否必須賦值❌ 可讀可寫,可不修改✅ 必須在所有路徑賦值
語意傳遞變數參考(雙向)單向輸出參數
適用場景需修改呼叫端變數、或避免大型結構體複製方法需回傳多個值(TryParse 模式)

程式碼示範

using System;

class RefOutDemo {
    // out:離開方法前必須對所有 out 參數賦值
    static void OutTest(out int x, out int y) {
        // x = y; // 錯誤:out 參數進入方法視為未初始化,不可讀取
        x = 1;
        y = 2; // 必須賦值
    }

    // ref:進入方法前必須已初始化,方法內可讀可寫
    static void RefTest(ref int x, ref int y) {
        x = 1;
        y = x; // 合法:可讀取 ref 參數
    }

    static void Main() {
        // out 測試
        int a, b;
        OutTest(out a, out b); // 未初始化也可
        Console.WriteLine($"a={a}, b={b}"); // 1, 2

        int c = 11, d = 22;
        OutTest(out c, out d); // 已初始化會被覆蓋
        Console.WriteLine($"c={c}, d={d}"); // 1, 2

        // ref 測試
        // int m, n; RefTest(ref m, ref n); // 編譯錯誤:未初始化
        int o = 11, p = 22;
        RefTest(ref o, ref p);
        Console.WriteLine($"o={o}, p={p}"); // 1, 1
    }
}

進階補充

  • C# 7.0+:支援 out var 內嵌宣告:OutTest(out var x, out var y);
  • 效能:對大型 struct,ref 可避免複製;但濫用會降低可讀性。
  • 遞迴/多執行緒:ref 共享同一記憶體位置,需注意競爭條件。
  • 不可用於:屬性存取器、索引子、非同步方法(async)、迭代器(yield return)。

記憶口訣

ref = 雙向通道(要先有值,可改可不改)
out = 單向出口(進來沒值,出去必須有值)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved