Я понимаю, что если я передаю тип значения ( int
, struct
и т. Д.) В качестве параметра (без ref
ключевого слова), копия этой переменной передается методу, но если я использую ref
ключевое слово, передается ссылка на эту переменную, не новый.
Но с ссылочными типами, такими как классы, даже без ref
ключевого слова, в метод передается ссылка, а не копия. Итак, что такое ref
ключевое слово с ссылочными типами?
Взять, к примеру:
var x = new Foo();
В чем разница между следующим?
void Bar(Foo y) {
y.Name = "2";
}
и
void Bar(ref Foo y) {
y.Name = "2";
}
c#
parameters
pass-by-reference
pass-by-value
Андреас Греч
источник
источник
Есть случаи, когда вы хотите изменить фактическую ссылку, а не объект, на который указывает:
источник
Джон Скит написал отличную статью о передаче параметров в C #. Он подробно описывает точное поведение и использование передаваемых параметров по значению, по ссылке (
ref
) и по выходу (out
).Вот важная цитата с этой страницы в отношении
ref
параметров:источник
Очень хорошо объяснено здесь: http://msdn.microsoft.com/en-us/library/s6938f28.aspx
Аннотация из статьи:
источник
Когда вы передаете ссылочный тип с ключевым словом ref, вы передаете ссылку по ссылке, и вызываемый вами метод может присвоить параметру новое значение. Это изменение будет распространяться на область вызова. Без ссылки ссылка передается по значению, а этого не происходит.
C # также имеет ключевое слово «out», которое очень похоже на ref, за исключением того, что с «ref» аргументы должны быть инициализированы перед вызовом метода, а с помощью «out» вы должны присвоить значение в получающем методе.
источник
Это позволяет вам изменять переданную ссылку. Например,
Вы также можете использовать , если вас не волнует ссылка, переданная в:
источник
Еще одна куча кода
источник
В дополнение к существующим ответам:
Как вы просили о разнице между двумя методами: нет никакой (ntra) дисперсии при использовании
ref
илиout
:источник
Параметр в методе, кажется, всегда передает копию, вопрос - копия чего. Копирование выполняется конструктором копирования для объекта, и поскольку все переменные являются объектами в C #, я считаю, что это относится ко всем из них. Переменные (объекты) похожи на людей, живущих по некоторым адресам. Мы либо меняем людей, живущих по этим адресам, либо можем создавать дополнительные ссылки на людей, живущих по этим адресам, в телефонной книге (делать мелкие копии). Таким образом, более одного идентификатора могут ссылаться на один и тот же адрес. Ссылочные типы требуют больше места, поэтому в отличие от типов значений, которые напрямую связаны стрелкой с их идентификатором в стеке, они имеют значение для другого адреса в куче (большее пространство для остановки). Это пространство нужно взять из кучи.
Тип значения: Идентификатор (содержит значение = адрес значения стека) ----> Значение типа значения
Тип ссылки: Идентификатор (содержит значение = адрес значения стека) ----> (содержит значение = адрес значения кучи) ----> Значение кучи (чаще всего содержит адреса к другим значениям), представьте больше стрелок, торчащих в разных направления к массиву [0], массиву [1], массиву [2]
Единственный способ изменить значение - следовать стрелкам. Если одна стрелка теряется / изменяется таким образом, значение недоступно.
источник
Ссылочные переменные переносят адрес из одного места в другое, поэтому любое их обновление в любом месте отразится на всех местах, КОГДА-то использует REF. Справочная переменная (405) работает до тех пор, пока не будет выделена новая память для справочной переменной, переданной в методе.
После выделения новой памяти (410) изменение значения этого объекта (408) не будет отражаться повсеместно. За этим реф приходит. Ref - это ссылка на ссылку, поэтому всякий раз, когда выделяется новая память, он узнает, потому что он указывает на это местоположение, поэтому значение может быть доступно всем everyOne. Вы можете увидеть изображение для большей ясности.
источник