C# 提供豐富的參數修飾詞,精確控制引數傳遞語意:值傳遞、參考傳遞、輸出參數、唯讀參考、可變參數,解決 C++ 參數模糊、Java 缺乏參考傳遞的問題。
| 修飾詞 | 傳遞語意 | 呼叫端 | 被呼叫端 | 適用場景 |
|---|---|---|---|---|
| (無) | 值傳遞 (參考型別傳參考複製) | 無 | 無 | 預設,輸入參數 |
ref | 參考傳遞 (雙向) | ref | ref | 需修改呼叫端變數、交換值 |
out | 輸出參數 (單向寫入) | out | out | 多重回傳值、TryParse 模式 |
in | 唯讀參考傳遞 (C# 7.2+) | in | in | 大型結構避免複製、保證不修改 |
params | 可變參數陣列 | 無/陣列 | params | 參數數量不固定 |
public static void Swap(ref int a, ref int b) {
(a, b) = (b, a); // C# 7.0 元組交換
}
// 呼叫
int x = 1, y = 2;
Swap(ref x, ref y); // 呼叫端也必須加 ref
Console.WriteLine($"{x}, {y}"); // 2, 1
public ref int FindFirstEven(int[] numbers) {
for (int i = 0; i < numbers.Length; i++)
if (numbers[i] % 2 == 0) return ref numbers[i];
throw new InvalidOperationException();
}
// 使用
int[] nums = { 1, 3, 4, 5 };
ref int even = ref FindFirstEven(nums);
even = 10; // 修改陣列元素
Console.WriteLine(nums[2]); // 10
public static bool TryParseInt(string s, out int result) {
return int.TryParse(s, out result); // 內建模式
}
// 使用
if (TryParseInt("42", out int value))
Console.WriteLine(value); // 42
// C# 7.0+ 內嵌宣告
if (int.TryParse("123", out var num))
Console.WriteLine(num);
public readonly struct LargeStruct {
public double X, Y, Z, W, A, B, C, D;
public double Magnitude => Math.Sqrt(X*X + Y*Y + Z*Z + W*W + A*A + B*B + C*C + D*D);
}
public static double Compute(in LargeStruct s) { // 避免複製 64 bytes
return s.Magnitude;
// s.X = 1; // 編譯錯誤:唯讀
}
// 使用
var s = new LargeStruct { X = 1, Y = 2 };
double m = Compute(s); // 隱含 in 傳遞
double m2 = Compute(in s); // 明確 in
readonly 方法/屬性時,編譯器建立防禦性複製readonly struct 避免複製
public static int Sum(params int[] numbers) {
int sum = 0;
foreach (int n in numbers) sum += n;
return sum;
}
// 使用
Sum(1, 2, 3); // 6
Sum(new[] { 1,2,3 }); // 6
Sum(); // 0
Sum(Array.Empty()); // 0
public static int Sum(params ReadOnlySpan numbers) { // 避免陣列配置
int sum = 0;
foreach (int n in numbers) sum += n;
return sum;
}
// C++: 呼叫端無法區分傳值/傳參考
void Func1(int x) { } // 傳值
void Func2(int& x) { } // 傳參考
void Func3(int* x) { } // 傳指標
int a = 1;
Func1(a); // 傳值
Func2(a); // 傳參考 - 呼叫端語法相同!
Func3(&a); // 傳指標 - 需取址
C# 強制呼叫端標註 ref/out/in,消除模糊,提升可讀性與安全性。
>= 16 bytes) 唯讀輸入用 in + readonly structref/out 過度使用,考慮回傳 Tuple/Record/物件C# 參數修飾詞提供精確的傳遞語意控制:ref 雙向、out 輸出、in 唯讀參考、params 可變參數。呼叫端強制標註消除 C++ 模糊問題,補足 Java 缺失。善用 in + readonly struct 可大幅提升大型值型別效能。