Что такое out в c
Перейти к содержимому

Что такое out в c

Модификатор параметров out (справочник по C#)

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

Ключевое слово out также можно использовать с параметром универсального типа для указания на то, что тип параметра является ковариантным. Дополнительные сведения об использовании ключевого слова out в этом контексте см. в разделе out .

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

Ключевые слова in , ref и out не считаются частью сигнатуры метода для разрешения перегрузки. Таким образом, методы не могут быть перегружены, если единственное различие состоит в том, что один метод принимает аргумент ref или in , а другой — out . Следующий код, например, компилироваться не будет.

Перегрузка допустима, если один метод принимает аргумент ref , in или out , а другой не использует ни один из этих модификаторов, как показано ниже.

Компилятор выбирает наиболее подходящую перегрузку, сравнивая модификаторы параметров в месте вызова с модификаторами параметров в вызове метода.

Свойства не являются переменными и поэтому не могут быть переданы как параметры out .

Ключевые слова in , ref и out запрещено использовать для следующих типов методов.

Асинхронные методы, которые определяются с помощью модификатора async.

Методы итератора, которые включают оператор yield return или .

Кроме того, методы расширения имеют следующие ограничения:

  • Ключевое слово out нельзя использовать в первом аргументе метода расширения.
  • Ключевое слово ref нельзя использовать в первом аргументе метода расширения, если аргумент не является структурой, или если универсальный тип не ограничен структурой.
  • Ключевое слово in нельзя использовать, если только первый аргумент не является структурой. Ключевое слово in нельзя использовать ни для одного универсального типа, даже если оно ограничено структурой.

Объявление параметров out

Объявление метода с аргументами out — стандартное решение для возвращения нескольких значений. Начиная с версии C# 7.0, вы можете использовать кортежи значений для таких сценариев. В следующем примере используется out для возвращения трех переменных с помощью вызова одного метода. Третьему аргументу присвоено значение NULL. Это позволяет методам возвращать значения по желанию.

Вызов метода с аргументом out

В C# 6 и более ранних версиях необходимо было объявлять переменную в отдельном операторе, прежде чем передавать ее как аргумент out . В следующем примере переменная number объявляется перед передачей в метод number , который пытается преобразовать строку в число.

Начиная с C# версии 7.0 переменную out можно объявлять в списке аргументов вызова метода, а не отдельно. Это делает код более кратким и удобным для восприятия, а также предотвращает непреднамеренное присвоение значения переменной перед вызовом метода. Следующий пример аналогичен предыдущему за тем исключением, что переменная number объявляется в вызове метода number .

В предыдущем примере переменная number строго типизирована как int . Вы также можете объявить неявно типизированную локальную переменную, как в приведенном ниже примере.

Спецификация языка C#

Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Модификаторы параметров

XYZ School

Mетоды могут как принимать, так и не принимать параметров, а также возвращать или не возвращать значения вызывающей стороне. Хотя определение метода в C# выглядит довольно понятно, существует несколько ключевых слов, с помощью которых можно управлять способом передачи аргументов интересующему методу:

Модификаторы параметров

Модификатор параметра Описание
(отсутствует) Если параметр не сопровождается модификатором, предполагается, что он должен передаваться по значению, т.е. вызываемый метод должен получать копию исходных данных
out Выходные параметры должны присваиваться вызываемым методом (и, следовательно, передаваться по ссылке). Если параметрам out в вызываемом методе значения не присвоены, компилятор сообщит об ошибке
ref Это значение первоначально присваивается вызывающим кодом и при желании может повторно присваиваться в вызываемом методе (поскольку данные также передаются по ссылке). Если параметрам ref в вызываемом методе значения не присвоены, компилятор никакой ошибки генерировать не будет
params Этот модификатор позволяет передавать в виде одного логического параметра переменное количество аргументов. В каждом методе может присутствовать только один модификатор params и он должен обязательно указываться последним в списке параметров. В реальности необходимость в использовании модификатора params возникает не особо часто, однако он применяется во многих методах внутри библиотек базовых классов

Нередко требуется, чтобы метод оперировал теми аргументами, которые ему передаются. Характерным тому примером служит метод Swap(), осуществляющий перестановку значений своих аргументов. Но поскольку аргументы простых типов передаются по значению, то, используя выбираемый в C# по умолчанию механизм вызова по значению для передачи аргумента параметру, невозможно написать метод, меняющий местами значения двух его аргументов, например типа int. Это затруднение разрешает модификатор ref.

Как вам должно быть уже известно, значение возвращается из метода вызывающей части программы с помощью оператора return. Но метод может одновременно возвратить лишь одно значение. А что, если из метода требуется возвратить два или более фрагментов информации, например, целую и дробную части числового значения с плавающей точкой? Такой метод можно написать, используя модификатор out.

Давайте отдельно рассмотрим роль каждого из вышеуказанных ключевых слов.

Модификатор ref

Модификатор параметра ref принудительно организует вызов по ссылке, а не по значению. Этот модификатор указывается как при объявлении, так и при вызове метода.

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

Выходные параметры

Это параметры, которые не нужно инициализировать перед передачей методу. Причина в том, что метод сам должен присваивать значения выходным параметрам перед выходом.

Ссылочные параметры

Эти параметры нужно обязательно инициализировать перед передачей методу. Причина в том, что они подразумевают передачу ссылки на уже существующую переменную. Если первоначальное значение ей не присвоено, это будет равнозначно выполнению операции над неинициализированной локальной переменной.

Давайте рассмотрим пример использования модификатора ref:

Модификатор ref

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

Модификатор out

Модификатор параметра out подобен модификатору ref, за одним исключением: он служит только для передачи значения за пределы метода. Поэтому переменной, используемой в качестве параметра out, не нужно (да и бесполезно) присваивать какое-то значение. Более того, в методе параметр out считается неинициализированным, т.е. предполагается, что у него отсутствует первоначальное значение. Это означает, что значение должно быть присвоено данному параметру в методе до его завершения. Следовательно, после вызова метода параметр out будет содержать некоторое значение.

Использование модификатора out

Обратите внимание, что использование модификатора out в данном примере позволяет возвращать из метода сразу четыре значения.

Модификатор params

В C# поддерживается использование массивов параметров за счет применения ключевого слова params. Ключевое слово params позволяет передавать методу переменное количество аргументов одного типа в виде единственного логического параметра. Аргументы, помеченные ключевым словом params, могут обрабатываться, если вызывающий код на их месте передает строго типизированный массив или разделенный запятыми список элементов.

Число элементов массива параметров будет равно числу аргументов, передаваемых методу. А для получения аргументов в программе организуется доступ к данному массиву:

Использование модификатора params

В тех случаях, когда у метода имеются обычные параметры, а также параметр переменной длины типа params, он должен быть указан последним в списке параметров данного метода. Но в любом случае параметр типа params должен быть единственным.

ref в сравнении с out в C#

Ключевые слова Ref и out в C# используются для передачи аргументов внутри метода или функции. Оба слова указывают на то, что аргумент/параметр передается по ссылке. По умолчанию параметры передаются в метод по значению. Используя эти ключевые слова ( ref и out ), мы можем передать параметр по ссылке.

Ключевое слово ref

Ключевое слово ref передает аргументы по ссылке. Это означает, что любые изменения, внесенные в этот аргумент в методе, будут отражены в этой переменной, когда управление вернется к вызывающему методу.

Пример кода

Вывод

Ключевое слово out

Ключевое слово out передает аргументы по ссылке. Это очень похоже на ключевое слово ref .

Пример кода

Вывод

Ref в сравнении с Out

Параметр или аргумент должен быть сначала инициализирован, прежде чем он будет передан в ref .

Инициализация параметра или аргумента перед передачей его в out не является обязательной.

Не требуется присваивать или инициализировать значение параметра (который передается по ref ) перед возвратом в вызывающий метод.

Вызываемый метод обязан присвоить или инициализировать значение параметра (который передается в out ) перед возвратом в вызывающий метод.

Передача значения параметра по Ref полезна, когда вызываемый метод также должен модифицировать передаваемый параметр.

Объявление параметра в методе out полезно, когда из функции или метода необходимо вернуть несколько значений.

Инициализация значения параметра перед его использованием в вызывающем методе не обязательна.

Значение параметра должно быть инициализировано в вызывающем методе перед его использованием.

Когда мы используем REF , данные могут передаваться двунаправленно.

Когда мы используем OUT , данные передаются только однонаправленно (от вызываемого метода к вызывающему методу).

И ref , и out по-разному обрабатываются во время выполнения программы, а во время компиляции они обрабатываются одинаково.

Свойства не являются переменными, поэтому они не могут быть переданы в качестве параметра out или ref .

Ключевое слово Ref / Out и перегрузка методов

И ref , и out обрабатываются по-разному во время выполнения программы, и одинаково во время компиляции, поэтому методы не могут быть перегружены, если один метод принимает аргумент как ref , а другой — как out .

Пример кода

Вывод при компиляции кода:

Однако перегрузка методов возможна, когда один метод принимает аргумент ref или out , а другой принимает тот же аргумент без ref или out .

Пример кода

Резюме

Ключевые слова out и ref полезны, когда мы хотим вернуть значение в тех же переменных, которые были переданы в качестве аргумента.

Материал подготовлен в рамках специализации «C# Developer». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *