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

C# 參數傳遞機制深度解析:值傳遞、ref、out、in 與參考類型行為

     編輯:關於C語言

核心概念

C# 參數傳遞分為 值傳遞(預設)與 參考傳遞(ref/out/in)。理解「參數本身」與「參數指向的物件」的區別,是避免常見 Bug 的關鍵。

四種傳遞模式比較

模式關鍵字可修改參數本身需初始化適用場景
值傳遞(無)否是唯讀輸入
參考傳遞ref是是雙向資料流、Swap
輸出參數out是否(方法內必指派)多重回傳值、TryParse 模式
唯讀參考in (C# 7.2+)否(編譯器強制)是大型結構體避免複製、唯讀傳遞

值類型傳遞行為

值傳遞:複製副本

void Square(int x) { x *= x; } // 只影響區域副本
int v = 5;
Square(v);
Console.WriteLine(v); // 5(未變)

ref 傳遞:共用儲存位置

void Square(ref int x) { x *= x; }
int v = 5;
Square(ref v);
Console.WriteLine(v); // 25(已變)

out 傳遞:強制輸出

bool TryParse(string s, out int result)
{
    return int.TryParse(s, out result);
}
TryParse("123", out int n); // n = 123

參考類型傳遞行為

參考類型變數儲存的是「物件參考」(指標)。

值傳遞參考類型:複製參考

void Modify(List list)
{
    list.Add(99);        // 影響原物件內容 ✓
    list = new List(); // 只改變區域參考,不影響呼叫端 ✗
}

var myList = new List { 1, 2 };
Modify(myList);
Console.WriteLine(myList.Count); // 3(內容被修改)

ref 傳遞參考類型:可替換物件

void Replace(ref List list)
{
    list = new List { 100 }; // 呼叫端的變數也會指向新物件
}

var myList = new List { 1, 2 };
Replace(ref myList);
Console.WriteLine(myList[0]); // 100

經典範例:Swap 實作

值類型 Swap

void Swap(ref int a, ref int b)
{
    int t = a; a = b; b = t;
}

參考類型 Swap

void Swap(ref string a, ref string b)
{
    string t = a; a = b; b = t;
}

陣列參數特殊行為

void ChangeArray(int[] arr)
{
    arr[0] = 999;      // 修改元素:影響原陣列
    arr = new int[3];  // 重新指派:不影響原陣列
}

void ChangeArrayRef(ref int[] arr)
{
    arr = new int[3];  // 影響原陣列參考
}

C# 7.2+ 新功能:in / ref readonly / ref struct

// 唯讀參考傳遞,避免大型結構體複製
readonly struct Vector3 { public double X, Y, Z; }
double Magnitude(in Vector3 v) => Math.Sqrt(v.X*v.X + v.Y*v.Y + v.Z*v.Z);

// ref readonly 回傳:避免複製且禁止修改
ref readonly Vector3 GetOrigin() => ref _origin;

// ref struct:只能存在於堆疊,適合高效能 Span-like 型別
ref struct Token { public ReadOnlySpan Text; }

最佳實務建議

  • 預設使用值傳遞:簡單、安全、意圖明確
  • 值類型需修改時用 ref:避免不必要的封箱
  • 多重回傳用 out 或 Tuple:TryGetValue(out var v) 或 (bool, T)
  • 大型結構體(>16 bytes)用 in:避免複製成本
  • 避免濫用 ref:增加耦合、降低可讀性、難以非同步化
  • 參考類型極少需 ref:除非確實要「換掉呼叫端的物件參考」

常見誤區釐清

「參考類型預設就是傳參考」——錯誤。預設是「值傳遞參考」,即複製指標。只有加上 ref 才是「參考傳遞參考」。

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