1. 參數的預設值
想像你去咖啡店:如果你沒特別說要不要加糖,barista 預設會幫你加一匙。但有時你想要……兩匙!或是完全不加糖(超猛der!)。方法也是一樣:有時候讓某些參數有預設值,沒特別指定時就用預設的,超方便。
命名參數就像你點咖啡時可以說:「牛奶我要豆漿,不是一般的」,不管配料平常是什麼順序都沒差。
在 C#,這兩個機制讓你的 code 更乾淨、更好用,也比較不會出 bug。這些東西在實際專案超常見:從 .NET library 到熱門 framework 都會用——所以老闆很愛看到你會用這些。
語法
參數的預設值直接在方法宣告時用 = 指定。如果呼叫方法時沒給這個參數,就會用你設定的預設值。
void PrintStudent(string name, int age = 18)
{
Console.WriteLine($"學生: {name}, 年齡: {age}");
}
怎麼運作?
- 如果呼叫 PrintStudent("Алиса"); — 會印出:學生: Алиса, 年齡: 18。
- 如果呼叫 PrintStudent("Саша", 22); — 會印出:學生: Саша, 年齡: 22。
所有型別都可以用嗎?
預設值可以給任何型別的參數,不過有些小細節:
- 參考型別(string、class 等):預設可以用 null 或直接給字串。
- 值型別(int、double、bool 等):就直接給對應型別的值。
- enum、struct 也都可以用預設值。
void AddStudent(string name, int course = 1, double averageScore = 5.0, string comment = null)
{
Console.WriteLine($"已新增學生: {name}, 課程: {course}, 平均分數: {averageScore}, 備註: {comment}");
}
呼叫範例:
- AddStudent("Иван");
- AddStudent("Мария", 2);
- AddStudent("Фёдор", 2, 4.7, "表現優異");
參數順序怎麼排?
所有非必要參數(有預設值的)都要放在右邊(也就是所有必要參數之後)。如果你把有預設值的參數放在必要參數前面,compiler 會直接翻桌。
// 錯誤!
void Test(int a = 1, int b)
{
// ...
}
為什麼? 不然 compiler 會搞不清楚你呼叫方法時哪個值要給哪個參數。
2. 命名參數
預設情況下,你呼叫方法時參數順序要跟方法定義一樣。但有時參數一堆,有些又有預設值,很容易搞混。
命名參數可以讓你直接指定要給哪個參數什麼值,順序完全沒差。
AddStudent(name: "Елизавета", averageScore: 4.2, comment: "本學期最佳學生");
- 這裡我們沒給課程(course),所以會用1(預設值)。
- 不用記 comment 是第幾個參數,直接寫名字就好。
你甚至可以顛倒參數順序:
AddStudent(averageScore: 3.7, name: "Георгий");
超方便,code 也變超好讀!
跟位置參數一起用
命名參數跟位置參數(沒名字的)可以混用,但所有位置參數要放在前面。
// 正確
AddStudent("Сергей", averageScore: 4.9);
// 錯誤
AddStudent(course: 2, "Филипп");
第一個命名參數之後,後面都只能用命名參數。 compiler 會很嚴格檢查這個順序,保護你不會踩雷。
多參數方法的便利性
這招超常用在參數一堆的方法。比如你要寫個 function 把 user 加到雲端資料庫:
void RegisterUser(
string username,
string password,
string email = null,
bool admin = false,
bool sendWelcomeEmail = true,
string language = "ru"
)
不用命名參數的呼叫看起來超可怕:
RegisterUser("cat", "qwerty", null, false, true, "ru");
用命名參數就超清楚又安全:
RegisterUser("cat", "qwerty", admin: true, sendWelcomeEmail: false, language: "en");
小建議:多用命名參數,這樣不用看文件也知道 code 在幹嘛!
3. 實作細節跟常見錯誤
剛開始用預設值跟命名參數時,超容易踩雷。
- 參數順序。 有預設值的參數一定要放在必要參數後面。順序錯 compiler 直接報錯。
- library 裡改預設值。 如果你在 library 裡改了預設值,舊的 client 不會自動用新值。預設值會被編進呼叫端的 code 裡。所以公開 library 的預設值要改前要想清楚。
- 混用位置跟命名參數。 如果你混用,但在命名參數後又給位置參數——這樣不行。例如:Func(a: 1, 2) —— 會報錯。
- 參數名拼錯。 compiler 超嚴格:拼錯(比如寫成 naem: "Миша"),會直接報錯:「沒有這個參數,你到底在幹嘛?!」。
GO TO FULL VERSION