1. 参数的默认值
想象一下你在咖啡店:如果你没说要不要加糖,咖啡师默认会加一勺。但有时候你想要……两勺!或者完全不加糖(勇士!)。方法参数也是一样:有时候让某些参数有个默认值会很方便,如果你没特别指定,就用默认的。
命名参数就像你点咖啡时说:“牛奶我要豆奶,不是普通的”,不管配料通常是什么顺序。
在C#里,这两种机制让你的代码更干净、更方便,也更不容易出错。它们在真实项目里很常见:从.NET库到各种流行框架——所以老板们很喜欢看到你会用这些。
语法
给函数参数设置默认值,就是在方法声明里直接用=。如果调用方法时没传这个参数,就用你写的默认值。
void PrintStudent(string name, int age = 18)
{
Console.WriteLine($"学生: {name}, 年龄: {age}");
}
参数
age的默认值
怎么用?
- 如果调用PrintStudent("Алиса"); —— 会输出:学生: Алиса, 年龄: 18。
- 如果调用PrintStudent("Саша", 22); —— 会输出:学生: Саша, 年龄: 22。
所有类型都能用吗?
默认值可以给任何类型的参数设置,但有点小细节:
- 引用类型(string、类等):默认值可以写null或者具体的字面量。
- 值类型(int、double、bool等):写你想要的字面量就行。
- 枚举(enum)、结构体:也可以用默认值。
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, "优秀");
带默认值参数的顺序
所有可选参数(有默认值的)必须放在右边(在所有必填参数后面)。如果你把有默认值的参数放在必填参数前面,编译器会很不爽地给你报错。
// 错误!
void Test(int a = 1, int b)
{
// ...
}
有默认值的参数不能放在必填参数前面
为啥这样? 因为否则编译器没法判断你传的参数到底是给哪个参数的。
2. 命名参数
默认情况下,调用方法传参数时,顺序必须和方法定义里参数的顺序一模一样。但有时候参数一堆,有些有默认值,很容易搞错。
命名参数让你可以明确指定每个参数的名字,顺序随便。
AddStudent(name: "Елизавета", averageScore: 4.2, comment: "本学期最佳学生");
用命名参数调用方法
- 这里我们没写年级(course),所以它会是1(默认值)。
- 不用记comment是第几个参数——直接写名字就行。
你甚至可以随便换顺序:
AddStudent(averageScore: 3.7, name: "Георгий");
命名参数顺序无所谓
超级方便,代码也更好懂!
和位置参数一起用
命名参数和位置参数(没写名字的)可以混着用,但所有位置参数必须在前面。
// 正确
AddStudent("Сергей", averageScore: 4.9);
// 错误
AddStudent(course: 2, "Филипп");
第一个命名参数后面,剩下的都必须是命名参数
第一个命名参数后,后面都只能用命名参数。 编译器会严格检查顺序,防止你踩坑。
多参数方法的便利性
当你用的方法有一堆可选项时,这招特别有用。比如你写个函数,把用户加到云数据库里:
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");
小贴士:用命名参数,让代码不用看文档也能懂!
3. 实现细节和常见坑
刚开始用默认值和命名参数时,容易在好几个地方踩坑。
- 参数顺序。 有默认值的参数一定要放在必填参数后面。顺序错了编译器就报错。
- 库里改默认值。 如果你在库里改了默认值,老的调用者不会自动用新值。默认值会被编译进调用代码里。所以改公共库的默认值前要想清楚。
- 混用位置参数和命名参数。 如果你混着用,但在命名参数后又写了位置参数——不行。比如:Func(a: 1, 2) —— 会报错。
- 参数名拼错。 编译器很严格:拼错了(比如写成naem: "Миша"),会报错,内容大概是:“没有这个参数,你在干嘛?!”。
GO TO FULL VERSION