CSharp 中形形色色的参数

必选参 与 可选参 与 不定参

CSharp 中参数有必选参, 可选参和不定参, 用以实现更加灵活的方法调用.

必选参

通常用的方法传参就是必选参. 只要方法有参数, 调用这个方法时就必须传参.

1
2
3
4
// 定义方法
public void Test(string str){
Debug.Log(str);
}

可选参

可选参对外表现为: 当外部调用方法时, 参数可以传也可以不传~ 哈哈, 任不任性?

那可选参是怎么编写的呢? 可选参就是给参数一个默认值, 此时参数就变成了可选参. 可选参也是有语法限制的, 可选参必须放到所有必选参的后面, 不定参不属于必选参.

1
2
3
4
// 定义方法
public void Test(string str, string star = "default value"){
Debug.Log(str + star);
}

调用具有可选参的方法时, 可以直接和正常的方法一样进行传参, 打算使用默认值的可选参可以直接省略.

1
2
3
// 调用方法
Test("abc");
Test("abc", "def")

但是这里有一个问题, 可选参的语法规则只限制了可选参必须在必选参的后面, 但是并没有限制可选参的数量, 如果有好多可选参, 而我想要只传递特定的参数的时候, 怎么办呢?

比如下面的方法我想使用 star1 的默认值, star2 我想改为 ", 你早就没了", 咋传参呢?

1
2
3
private static void Test(string str, string star1 = "我没带腰带", string star2 = "star2") {
Debug.Log(str + star1 + star2);
}

此时就得使用可选参的另一种调用方式: 参数名: 参数值.

1
Test("要不是因为", star2: ", 你早就没了");

不定参

编写程序的时候, 有时会有这样的场景: 我需要写一个工具方法用来处理各种数据, 数据使用参数的形式传入方法, 但是问题在于每次我要传入的数据的数量都是不一致的, 这次可能传入 4 个, 下次可能需要 5 个, 甚至有时需要 10 个也说不定, 那这可咋办呢?

在没有不定参之前, 只能使用数组来传输, 参数为一个数组, 传入数据的时候先将数据整合为一个数组, 然后整体传入, 但是如果我就是想逐个传入呢? 就像 string.Format("{0}, {1}, {2}", "AAA", "BBB", "CCC"); 一样, 后面的参数数量不确定, 并且传入的时候是逐个传入的.

此时就需要语法糖-不定参啦! 不定参的对外表现就是可以传入同类型的数据任意多个, 数量是不确定的, 传入的时候参数也是允许逐个传入的.

不定参使用 params 关键字和 数组 实现. 切记必须是 数组 类型.

即从外部看来, 参数传入时是逐个传入的, 但是实际在传入之后会被整合为一个数组进行处理, 这也就是为什么数量可以不确定, 但类型必须是同类型的原因.

1
2
3
4
5
6
7
8
9
10
11
12
13
// 不定参方法
public void UseParams(params string[] stars) {
foreach (var star in stars) {
Debug.Log(star);
}
}

// 调用 (同类型, 数量不定, 可以逐个传入, 可以整体作为数组传入)
UseParams();
UseParams("AAA");
UseParams("AAA", "BBB");
UseParams("AAA", "BBB", "CCC");
UseParams(new[]{"AAA", "BBB", "CCC"});

另外不定参也有语法要求, 不定参作为参数时, 必须放置在整个参数列表的最后.

总结

可选参:

  1. 参数具有默认值.
  2. 传参时可传可不传.
  3. 可同时定义多个可选参.
  4. 可以使用 "参数名: 参数值" 进行指定参数传值.

不定参

  1. 参数必须同类型.
  2. 参数数量不确定, 且允许逐个传入.
  3. 1 个参数列表中不定参最多只能有 1 个.
  4. 使用 params 和 [] 实现. (是否仅此一种待考究, 目前暂时认为唯一方式)

参数顺序

( 必选参, 可选参, 不定参 )

this 修饰的参数

无论是带有默认值的可选参还是使用 params 关键字的不定参, 它们的本质还是为了方法的参数服务的, 但是还有一种是使用了 this 关键字进行修饰的参数.

使用 this 修饰更多的是为了类而服务, 目的是为了对类进行方法扩展.

目前理解为: 使用 this 来实现 扩展方法, 对特定的非静态类进行行为补充. 切记是非静态类.

比如有一个非静态类已经封装好了, 我们无法去修改类文件, 那么此时想要对其增加行为的话就可以使用这个语法.

下面是一个 Student 类, 这个类文件已经无法查看与修改.

1
2
3
4
5
// 简易类, 举例用
public class Student {
public string name;
public string id;
}

此时在另一个地方使用这个类的一个实例, 需要增加一个特定的功能, 就可以这样写:

1
2
3
4
5
6
7
8
// 先为这个 Student 添加想要的功能
private static void NewAction(this Student student, string str) {
Debug.Log($"{student.name} : {student.id}, {str}");
}

// 之后就可以使用类的实例直接调用
var student = new Student {name = "Kuroha", id = "0001"};
student.NewAction("就是我啦!");

此语法还可以对 CSharp 原始类型进行扩展, 比如 int, string 等. 扩展方法也是具有语法限制的, 都放在总结里面了.

  1. 使用 this 可以实现特定类型的方法扩展.
  2. this 修饰的参数并不需要主动传参, 这个参数的值就是调用时类实例的值.
  3. 扩展方法只能在非嵌套, 非泛型的静态类内部才能定义.
  4. 扩展方法必须是静态方法. (毕竟在静态类中嘛)
  5. 调用时必须使用实例进行调用. (虽然定义的时候是一个静态方法)
  6. this 修饰的参数必须位于参数列表的第 1 个! (正好和 params 相反)