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); 

发表评论

© 2022 狸玖技术站 - 基于 WordPress