C# 参数
C#参数
方法可以具有参数序列。
参数定义必须为该方法提供的参数集。
在以下示例中,myMethod
方法具有名为p
的单个参数,类型为int
:
static void myMethod (int p) {
p = p + 1; // Increment p by 1
Console.WriteLine(p); // Write p to screen
}
static void Main() {
myMethod (8);
}
我们可以控制参数如何通过 ref
和 out
修饰符传递。
下表列出了 ref
和 out
修饰符的功能。
修饰符 | 项目 | 变量必须明确赋值 |
---|---|---|
(None) | Value | Going in |
ref | Reference | Going in |
out | Reference | Going out |
按值传递参数
默认情况下,C#中的参数通过值传递。按值传递意味着在传递给方法时将创建值的副本:
class Main {
static void myMethod (int p) {
p = p + 1; // Increment p by 1
Console.WriteLine (p); // Write p to screen
}
static void Main() {
int x = 8;
myMethod (x); // Make a copy of x
Console.WriteLine (x); // x will still be 8
}
}
赋值 p
新值不会更改 x
的内容。
按值传递引用类型参数会复制引用,而不是对象。
在下面的示例中, myMethod
看到与 Main
实例化相同的StringBuilder
对象,但具有对它的独立引用。
sb
和 myMethodSB
是引用同一个StringBuilder
对象的两个不同的变量:
class Main {
static void myMethod (StringBuilder myMethodSB) {
myMethodSB.Append ("test");
myMethodSB = null;
}
static void Main() {
StringBuilder sb = new StringBuilder();
myMethod (sb);
Console.WriteLine (sb.ToString()); // test
}
}
myMethodSB
是引用的副本,将其设置为 null
不会使sb为null。
ref修饰符
为了通过引用,C#提供ref
参数修饰符。
在以下示例中,p
和 x
指的是相同的存储器位置:
class Test {
static void myMethod (ref int p) {
p = p + 1; // Increment p by 1
Console.WriteLine (p); // Write p to screen
}
static void Main(){
int x = 8;
myMethod (ref x); // Ask myMethod to deal directly with x
Console.WriteLine (x); // x is now 9
}
}
赋值 p
一个新值将更改 x
。
在编写和调用方法时都需要ref
修饰符。
以下代码显示如何使用 ref
修饰符创建交换方法:
class Test {
static void Swap (ref string a, ref string b){
string temp = a;
a = b;
b = temp;
}
static void Main() {
string x = "A";
string y = "B";
Swap (ref x, ref y);
Console.WriteLine (x);
Console.WriteLine (y);
}
}
参数可以通过引用或按值传递,而不管参数类型是引用类型还是值类型。
out修饰符
out参数就像一个 ref
参数,除了它:
- 在进入函数之前不需要赋值
- 必须在它出来的函数之前赋值
out
修饰符用于从方法获取多个返回值。
例如:
class Test {
static void ToWords (string name, out string firstNames, out string lastName) {
int i = name.LastIndexOf (" ");
firstNames = name.Substring (0, i);
lastName = name.Substring (i + 1);
}
static void Main(){
string a, b;
ToWords("this is a test", out a, out b);
Console.WriteLine (a);
Console.WriteLine (b);
}
}
像 ref
参数一样,out
参数通过引用传递。
params修饰符
params
参数修饰符用于方法的最后一个参数,以便该方法接受任意数量的特定类型的参数。
参数类型必须声明为数组。
例如:
class Test {
static int Sum (params int[] ints) {
int sum = 0;
for (int i = 0; i < ints.Length; i++) {
sum += ints[i]; // Increase sum by ints[i]
}
return sum;
}
static void Main(){
int total = Sum (1, 2, 3, 4);
Console.WriteLine (total); // 10
}
}
我们还可以提供一个 params
参数作为普通数组。
int total = Sum (new int[] { 1, 2, 3, 4 } );
可选参数
C#方法,构造函数和索引器可以声明可选参数。
如果参数在其声明中指定了默认值,那么该参数是可选的:
void myMethod (int x = 23) {
Console.WriteLine (x);
}
调用方法时可以省略可选参数:
myMethod(); // 23
默认参数23实际上传递给可选参数x
。
前面对myMethod的调用在语义上与:
myMethod (23);
可选参数不能用 ref
或 out
标记。
可选参数的默认值必须是常量表达式,或值类型的参数较少的构造函数。
强制参数必须在方法声明和方法调用中的可选参数之前发生。
在以下示例中,显式值1传递给 x
,默认值0传递给 y
:
void myMethod (int x = 0, int y = 0) {
Console.WriteLine (x + ", " + y);
}
void Test() {
myMethod(1); // 1, 0
}
要将默认值传递给 x
和显式值为 y
,我们必须将可选参数与命名参数组合。
命名参数
我们可以通过名称识别参数。例如:
void myMethod (int x, int y) {
Console.WriteLine (x + ", " + y);
}
void Test() {
myMethod (x:1, y:2); // 1, 2
}
命名参数可以以任何顺序发生。
以下对myMethod的调用在语义上是相同的:
myMethod (x:1, y:2);
myMethod (y:2, x:1);
我们可以混合命名和位置参数:
myMethod (1, y:2);
位置参数必须在命名参数之前。
所以我们不能这样调用 myMethod
:
myMethod (x:1, 2); // Compile-time error
命名参数对可选参数很有用。
例如,考虑以下方法:
void myMethod (int a = 0, int b = 0, int c = 0, int d = 0) { ... }
我们可以调用这个方法只为 d
提供一个值,如下所示:
myMethod (d:3);
更多建议: