| 特性 | ref | out |
|---|---|---|
| 語義 | 引用傳遞:讀取並修改調用者變量 | 輸出傳遞:僅用於向調用者返回值 |
| 調用前初始化 | 必須 初始化 | 不需要 初始化(方法內必須賦值) |
| 方法內讀取 | 允許讀取初始值 | 讀取前必須賦值,否則編譯錯誤 |
| 適用場景 | 需雙向傳遞數據(如 TryParse 並修改原值) | 純輸出參數(如 TryParse、多返回值) |
// ref 示例
void Swap(ref int a, ref int b) { int t=a; a=b; b=t; }
int x=1, y=2; Swap(ref x, ref y); // x=2, y=1
// out 示例
bool TryGetValue(string key, out int value) {
if (dict.TryGetValue(key, out value)) return true;
value = -1; // 必須賦值
return false;
}
int val;
if (TryGetValue("key", out val)) { ... }
兩者在 IL 中均為 &(by reference),區別在於編譯器施加的確定性賦值規則(Definite Assignment Rules)。
out是傳出參數,ref是引用參數,前者強調的是傳出,也就是在此之前傳入是無關緊要的。後者強調的是傳入/修改。兩者在用法上也不同,比如out必須初始化。