参数传递:ref 和 out

以下是你提供的 HTML 片段内容转换成 Markdown 格式后的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
### C# 参数传递:ref 和 out

在 C# 中,普通参数传递是按值传递的,这意味着在函数内部对参数的修改不会影响到函数外部的变量。为了在函数内部修改外部变量的值,我们可以使用 `ref``out` 关键字。以下是它们的用法和区别:

#### 按值传递示例

```csharp
static void Main(string[] args)
{
int b = 5;
ChangeValue(b);
Console.WriteLine(b);
}
static void ChangeValue(int a)
{
a = 10;
}
```

在这个示例中,虽然在 `ChangeValue` 方法中修改了参数 `a` 的值,但 `Main` 方法中的变量 `b` 并没有受到影响。

#### 使用 ref 关键字

`ref` 关键字用于按引用传递参数,使得在函数内部的修改能够影响到函数外部的变量。

```csharp
static void Main(string[] args)
{
int b = 5;
ChangeRef(ref b);
Console.WriteLine(b);
}
static void ChangeRef(ref int a)
{
a = 10;
}
```

在这个示例中,`ref` 关键字使得 `ChangeRef` 方法内部对参数 `a` 的修改能够反映到 `Main` 方法中的变量 `b` 上。

#### 使用 out 关键字

`out` 关键字与 `ref` 类似,但主要用于方法返回多个值的情况。

```csharp
static void Main(string[] args)
{
int b;
ChangeOut(out b);
Console.WriteLine(b);
}
static void ChangeOut(out int a)
{
a = 10;
}
```

在这个示例中,使用 `out` 关键字允许在函数内部对未初始化的变量进行赋值,并将该值传回到函数外部。

#### ref 和 out 的区别

1. **初始化要求:**
- `ref` 参数在传递前必须初始化。
- `out` 参数在传递前不需要初始化。
2. **赋值要求:**
- `ref` 参数在方法内部不要求必须赋值。
- `out` 参数在方法内部必须赋值。

### 示例代码总结

```csharp
class Program
{
static void Main(string[] args)
{
int b = 5;
ChangeRef(ref b);
Console.WriteLine(b);

int c;
ChangeOut(out c);
Console.WriteLine(c);
}

static void ChangeRef(ref int a)
{
a = 10;
}

static void ChangeOut(out int a)
{
a = 10;
}
}
```

注:C# 7.0 之前的写法使用 `out` 必须预先声明,在 C# 7.0 及更高版本中可以使用内联声明。

**内联声明 (Inline declaration):**
这个语法允许直接在方法调用参数列表中声明新的变量,不需要预先声明 `index` 变量,编译器会自动推断并创建这个变量。

**变量作用域:**

- 通过内联方式声明的 `index` 变量
- 其作用域会扩展到包含它的代码块(如整个 if 语句块)
- 但在 if 条件判断之后,后续代码将无法访问这个变量