int someValue = 5;
add(ref someValue)
Console.WriteLine(someValue) // 6
void add(ref int i) => i++;
out 和 in 是 ref 的有限版本
out 允许您获取引用,但不允许您从中读取外部值。因此,out 保证您必须传递一个 ref,其中任何数据都将被 100% 删除。出于同样的原因,out 要求您为其分配一些内容(即使它为 null)。例如,在tryGetValue中使用 Out ,它允许您同时检查属性是否存在并获取值
bool tryGetValue(int id, out object? x){
if (data.Contains(id)) {
x = data.get(id);
return true;
}
// Главная цель затереть предыдущие данные из ref
// Поэтому мы можем присвоить переменной значение null
x = null;
return false;
}
HugeData someData = new HugeData();
displayData(in someData); // someData не копируется
void displayData(in HugeData data) => ...
struct HugeData {
// Много данных
}
// btw структуры являются типами значений (как и int, short и т. п.)
// это значит что обычно они лежат на стеке
// и при передаче в виде аргумента копируются
// при этом изменяя их оригинал не меняется, как с объектами
所有这 3 个关键字都传递一个引用(类似于 C++ 中的 &T)。
通过将 ref 传递给该方法,我们传递了对带有该变量值的内存部分的引用,并且通过更改该变量,同一内存部分也会发生变化。我们可以更改原始变量,甚至可以为其分配新值
out 和 in 是 ref 的有限版本
out 允许您获取引用,但不允许您从中读取外部值。因此,out 保证您必须传递一个 ref,其中任何数据都将被 100% 删除。出于同样的原因,out 要求您为其分配一些内容(即使它为 null)。例如,在tryGetValue中使用 Out ,它允许您同时检查属性是否存在并获取值
反过来,又提供了一个不可写的引用。它很少使用,例如,您有一个大型结构,或者堆栈上的数组。通过将其传递给方法,它被完全复制,我们可以通过仅传递引用来避免这种情况。保证链接不会被更改。在使用动态库时它通常很有用(因为它们通常返回指向结构的指针)