По умолчанию, если мы передаём в метод параметр значимого типа, то передаётся копия его значения. Если ссылочного, то ссылка на этот объект в памяти (в данном случае все изменения, проведённые с этим аргументом, будут сохранены, в первом же случае - нет)
CLR также позволяет передавать параметры по ссылке, а не по значению. В C# это делается с помощью ключевых слов out и ref. Оба заставляют компилятор генерировать метаданные, описывающие параметр как переданный по ссылке. Компилятор использует эти метаданные для генерирования кода, передающего вместо самого параметра его адрес.
Поведение ссылочных и значимых типов при использовании ключевых слов out и ref различается значительно. Вот как это выглядит в случае значимого типа:
public sealed class Program {
public static void Main() {
Int32 x; // Инициализация x
GetVal(out x); // Инициализация x не обязательна
Console.WriteLine(x); // Выводится 10
}
private static void GetVal(out Int32 v) {
v = 10; // Этот метод должен инициализировать переменную V
}
}
А теперь рассмотрим аналогичный пример с ключевым словом ref:
public sealed class Program {
public static void Main() {
Int32 x = 5; // Инициализация x
AddVal(ref x); // x требуется инициализировать
Console.WriteLine(x); // Выводится 15
}
private static void AddVal(ref Int32 v) {
v += 10; // Этот метод может использовать инициализированный параметр v
}
}