Почему в C # есть и out, и ref?


18

C # имеет outи refключевые слова. Почему эти два необходимы? Отказ от ответственности: у меня нет глубоких знаний C #.


3
Нет ли дублирования между сайтами в переполнении стека?
Питер Мортенсен


2
Вы спрашиваете о разнице между refи out? Или вы спрашиваете, что такое использование аргументов по ссылкам ref/ outпо сравнению с аргументами по значению (без модификатора параметра)? Или оба?
Джеппе Стиг Нильсен

1
Я чувствую, что этот вопрос похож, но не совсем дурак - по крайней мере, если он взят с точки зрения языкового дизайна
jmoreno

Ответы:


32

С точки зрения реализации они, по сути, одно и то же, но outсообщают о чем-то, что refне имеет значения: вас не волнует вклад. Это означает определенные вещи для вас и для инструментов. Например, вы можете передать неинициализированную переменную outпараметру, и это не проблема, где бы это было иначе, и внутри функции вы должны присвоить значение outпараметру до его возврата, тогда как нет необходимости делать что-либо в все со refзначением.


10
Ref vs out гораздо важнее для компилятора, чем для программиста. Компилятор обязан убедиться, что вы не читаете переменную до того, как ей присвоено значение, и outдает ему способ сделать это, который лучше всего соответствует тому, как вы хотите работать с переменными в первую очередь.
Корт Аммон - Восстановить Монику

Не могли бы вы уточнить, что «out» сообщает то, чего не делает «ref».
Нео

4
@Neo: В основном то, что я сказал в ответе: оно сообщает, что вам не нужно использовать это для ввода, и, таким образом, безопасно передавать неинициализированное значение outпараметру, потому что функция, получающая его, не будет читать из него ,
Мейсон Уилер

@MasonWheeler Разрешено ли это (и / или принудительно применено на принимающей стороне) верификатором? Вне это просто атрибут, внутренне.
Random832,

@ Random832: Как Роберт опубликовал под своим ответом, взгляните на Эрика Липперта (бывшего парня из компилятора C #), обсуждающего это на stackoverflow.com/q/2876315
Мейсон Уилер

7

Чтобы понять эти два ключевых слова, вам нужно понять, что означает передача значения по ссылке . По сути, это означает, что если вы изменяете переменную параметра, которую вы передаете в метод или функцию, эта переменная сохраняет свое измененное значение при выходе из функции. Объявление параметра как refили outвыполнение этого, тогда как обычная переменная параметра сохранит свое первоначальное значение, даже если вы изменили его в функции.

Единственное различие между refи outзаключается в том, outчто вам не нужно инициализировать переменную перед тем, как передать ее в функцию, но refэто необходимо; в то время как out действительно требуют , чтобы назначить что - то к переменной внутри функции, но refне делает.


Разве нет разницы, связанной с дисперсией?
одноклеточный

См. Ответ Эрика Липперта на stackoverflow.com/q/2876315
Роберт Харви

2

Ты спрашивал.

C # есть и ref, почему эти два требуются. У меня нет глубоких знаний C #. Почему выход и ref параметры обязательны?

И ответ заключается в том, что они НЕ ТРЕБУЮТСЯ, например, java не имеет ни одного, а VB имеет только ref (и требует этого только в объявлении метода).

Вы можете легко написать целую программу, не используя ни того, ни другого.

Они существуют, потому что они иногда полезны. Вот почему их два, а не только один - потому что полезно проводить различие между «здесь есть что-то, измените его, если хотите» и «придайте этой вещи новое значение».

Другие языки имеют разные приоритеты и могут включать или не включать их или эквивалентные. Они могут даже не согласиться с тем, является ли один из них полезным, и поэтому могут активно решать НЕ реализовывать одно или другое.


1

По своей сути , как refи outобеспечить механизм для передачи адреса переменных к способу , так что он может быть обновлен - назначение на refили outпараметр обновляет переменную в контексте вызывающего абонента. В чем они отличаются, так это в гарантиях: outгарантий, что переменная будет обновлена, refнет.

С другой стороны вызова есть аналогичные различия. outПараметр нашего метода не гарантируется содержит ничего полезного по прибытии и должен быть установлен на значение в какой - то момент, в то время как refпараметр можно предположить , что он имеет значение , и мы не должны делать ничего конкретного с ним.

Это различие влияет на анализ, генерацию и оптимизацию кода, которые, в большинстве случаев, не слишком очевидны для нас, но могут повлиять на работу наших программ. Генератор кода может отложить выделение переменной до момента, предшествующего вызову, оптимизатор может решить, что он может более эффективно переупорядочить некоторые операции на основе контракта и т. Д.

С точки зрения использования: как общее правило, я использую outдля ситуаций, когда меня не волнует содержание переменной, когда она поступает в качестве параметра и refкогда я делаю.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.