ZetCode

C# ref, out, in

最后修改于 2023 年 7 月 5 日

C# ref, out, in 关键字教程解释了 ref/out/in 关键字之间的差异,并展示了如何使用它们。

在 C# 中,方法参数默认按值传递。我们使用 ref 关键字来按引用传递值。当我们按引用传递值时,方法接收到实际值的引用。原始值在修改时会受到影响。ref 要求变量在传递之前被初始化。ref 修饰符必须在方法定义和方法调用中使用。outin 关键字是 ref 的一些修改。

out 关键字也会导致参数按引用传递。与 ref 不同,它不要求传递的变量预先初始化。要使用 out 参数,方法定义和调用方法都必须显式地使用 out 关键字。

in 关键字导致参数按引用传递,但确保参数不被修改。作为 in 参数传递的变量必须在方法调用中传递之前进行初始化。

当重载方法时,它们的签名不能仅因 inrefout 而不同。当一个方法没有其中一个修饰符而另一个方法有修饰符时,重载是可能的。

inrefout 修饰符具有以下限制:

C# ref 修饰符示例

以下示例使用 ref 关键字来更改两个变量的值。

Program.cs
int a = 4;
int b = 7;

Console.WriteLine("Outside Swap method");
Console.WriteLine($"a is {a}");
Console.WriteLine($"b is {b}");

Swap(ref a, ref b);

Console.WriteLine("Outside Swap method");
Console.WriteLine($"a is {a}");
Console.WriteLine($"b is {b}");

void Swap(ref int a, ref int b)
{
    int temp = a;
    a = b;
    b = temp;

    Console.WriteLine("Inside Swap method");
    Console.WriteLine($"a is {a}");
    Console.WriteLine($"b is {b}");
}

原始变量在 Swap 方法内部被更改。

Swap(ref a, ref b); 
...
void Swap(ref int a, ref int b)

请注意,方法调用和方法定义都使用 ref 关键字。

$ dotnet run 
Outside Swap method
a is 4
b is 7
Inside Swap method
a is 7
b is 4
Outside Swap method
a is 7
b is 4

C# out 修饰符示例

以下示例使用 out 修饰符。

Program.cs
ReadName(out string? name);
Console.WriteLine(name);

void ReadName(out string? name) {

    Console.Write("Enter your name: ");
    name = Console.ReadLine();
}

在本示例中,我们从用户读取输入。输入存储在一个变量中,该变量具有 out 修饰符。name 变量在使用之前未定义。

ReadName(out string? name);
...
void ReadName(out string? name) {

out 关键字用于方法调用和定义。

$ dotnet run 
Enter your name: Peter
Peter

C# in 修饰符示例

在以下示例中,我们使用 in 修饰符。

Program.cs
string msg = "an old falcon";
Modify(in msg);

void Modify(in string msg) {

    msg = "a young eagle";
}    

我们尝试修改 msg 变量,但编译以错误消息结束:error CS8331: Cannot assign to variable 'in string' because it is a readonly variable(错误 CS8331:无法赋值给变量 'in string',因为它是一个只读变量)

来源

C# 语言参考

在本文中,我们介绍了 C# ref、out 和 in 关键字。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程