В C # я всегда думал, что непримитивные переменные передаются по ссылке, а примитивные значения передаются по значению.
Таким образом, при передаче методу любого не примитивного объекта, все, что делается с объектом в методе, будет влиять на передаваемый объект. (C # 101 материал)
Тем не менее, я заметил, что когда я передаю объект System.Drawing.Image, что это не так? Если я передам объект system.drawing.image другому методу и загрузлю изображение в этот объект, то позволю этому методу выйти из области видимости и вернуться к вызывающему методу, это изображение не загружено в исходный объект?
Почему это?
Ответы:
Объекты не передаются вообще. По умолчанию аргумент оценивается, и его значение передается по значению как начальное значение параметра вызываемого вами метода. Теперь важным моментом является то, что значение является ссылкой для ссылочных типов - способ добраться до объекта (или ноль). Изменения в этом объекте будут видны из звонящего. Однако изменение значения параметра для ссылки на другой объект не будет отображаться при использовании передачи по значению, которая используется по умолчанию для всех типов.
Если вы хотите использовать передачу по ссылке, вы должны использовать
out
илиref
, является ли тип параметра типом значения или ссылочным типом. В этом случае, по сути, сама переменная передается по ссылке, поэтому параметр использует то же место хранения, что и аргумент, - и вызывающий видит изменения в самом параметре.Так:
У меня есть статья, которая более подробно рассказывает об этом . По сути, «передача по ссылке» не означает, что вы думаете, что это значит.
источник
ref
иout
из c #, можно ли сказать, что c # передает параметры так же, как это делает java, то есть всегда по значению. Есть ли разница с Java.Еще один пример кода, чтобы продемонстрировать это:
И вывод:
источник
Много хороших ответов было добавлено. Я все еще хочу внести свой вклад, возможно, это прояснит немного больше.
Когда вы передаете экземпляр в качестве аргумента методу, он передает
copy
экземпляр. Теперь, если передаваемый вами экземпляр являетсяvalue type
(находится вstack
), вы передаете копию этого значения, поэтому, если вы измените его, оно не будет отражено в вызывающей программе. Если экземпляр является ссылочным типом, вы передаете копию ссылки (снова находится вstack
) объекту. Итак, вы получили две ссылки на один и тот же объект. Оба они могут изменить объект. Но если в теле метода вы создадите новый объект, ваша копия ссылки больше не будет ссылаться на исходный объект, она будет ссылаться на новый объект, который вы только что создали. Таким образом, вы получите 2 ссылки и 2 объекта.источник
Я думаю, это понятнее, когда вы делаете это так. Я рекомендую скачать LinqPad для тестирования подобных вещей.
И это должно вывести
WontUpdate
Имя: Эгли, Фамилия: Бесерра
UpdateImplicitly
Имя: Фавио, Фамилия: Бесерра
UpdateExplicitly
Имя: Фавио, Фамилия: Бесерра
источник
Когда вы передаете
System.Drawing.Image
объект типа методу, вы фактически передаете копию ссылки на этот объект.Так что, если внутри этого метода вы загружаете новое изображение, вы загружаете, используя новую / скопированную ссылку. Вы не вносите изменения в оригинал.
источник
Как вы передали объект в метод?
Вы делаете новый внутри этого метода для объекта? Если это так, вы должны использовать
ref
в методе.Следующая ссылка даст вам лучшую идею.
http://dotnetstep.blogspot.com/2008/09/passing-reference-type-byval-or-byref.html
источник
При передаче по ссылке вы только добавляете «ref» в параметры функции, и еще одна вещь, которую вы должны объявить функцией «static», потому что main - это static (#
public void main(String[] args)
)!источник