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

C# 方法參數傳遞四大模式:值、ref、out、params 深度解析與實戰陷阱

     編輯:關於C#

四種參數模式完整對比

模式關鍵字記憶體行為初始化要求資料流向典型用途
值參數(無)複製值 (值型別) 或複製參考 (參考型別)呼叫端必須已指派單向 (進)預設、唯讀輸入
參考參數ref傳遞變數位址 (別名)呼叫端必須已指派雙向 (進/出)修改呼叫端變數、大型結構體避免複製
輸出參數out傳遞變數位址 (別名)呼叫端無需初始化,被呼叫端必須指派單向 (出)多傳回值、TryParse 模式
參數陣列params建立陣列實例封裝引數呼叫端可提供 0~N 個引數單向 (進)可變參數個數、便利呼叫

值參數:參考型別的「複製參考」陷阱


void ModifyList(List list) {
    list.Add(99);        // 修改「共享物件」內容 → 影響呼叫端
    list = new List(); // 修改「區域參考」 → 不影響呼叫端
}

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

值參數傳遞參考型別時,複製的是參考值,雙方指向同一物件。若需完全隔離,需手動深層複製。

ref 參數:交換兩個變數經典範例


void Swap(ref int x, ref int y) {
    int temp = x; x = y; y = temp;
}

int a = 1, b = 2;
Swap(ref a, ref b);
Console.WriteLine($"a={a}, b={b}"); // a=2, b=1

ref 區域變數別名陷阱


void AliasDemo(ref string s1, ref string s2) {
    s1 = "Changed";
}

string str = "Original";
AliasDemo(ref str, ref str); // 同一變數傳遞兩次
Console.WriteLine(str); // "Changed" - 兩個參數指向同一儲存位置

out 參數:TryParse 模式標準實作


bool TryParseInt(string input, out int result) {
    // 必須在所有路徑指派 result
    if (int.TryParse(input, out result)) return true;
    result = 0; // 失敗時也要指派
    return false;
}

// 使用 (C# 7+ 內建 out 變數宣告)
if (TryParseInt("123", out int value))
    Console.WriteLine(value);

params 參數陣列:規則與最佳實務

  • 必須是最後一個參數。
  • 只能有一個 params 參數。
  • 型別必須是一維陣列 (int[]、string[]),不可為多維陣列 (int[,])。
  • 不可與 ref/out 結合。

void Log(params string[] messages) {
    foreach (var msg in messages) Console.WriteLine($"[LOG] {msg}");
}

// 多種呼叫方式
Log();                           // 空陣列
Log("Single");                   // 隱含轉換
Log("A", "B", "C");              // 隱含建立陣列
Log(new[] { "X", "Y" });         // 顯式陣列

現代 C# 進階參數特性

特性語法說明
預設參數值void M(int x = 10)編譯器在呼叫端插入預設值,非虛擬方法才安全
命名引數M(y: 5, x: 3)順序無關,提升可讀性
ref 回傳ref int Find(int[] arr, int val)回傳陣列元素別名,可直接修改元素
in 參數void M(in readonly int x)唯讀參考傳遞,避免複製大型結構體
out 變數宣告TryParse(s, out int v)C# 7+ 內建宣告,無需預先宣告

設計決策流程圖

  1. 需修改呼叫端變數? → ref
  2. 需輸出多個值且呼叫端無初始值? → out
  3. 參數個數不固定? → params
  4. 大型結構體唯讀傳遞? → in (C# 7.2+)
  5. 預設情況 → 值參數
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved