В чем разница между параметрами ref
и out
в .NET? Каковы ситуации, когда можно быть более полезными, чем другие? Что было бы фрагментом кода, где можно было бы использовать, а другое не могло?
Разница между параметрами ref и out в .NET.
Ответ 1
Они почти одинаковы - единственное отличие состоит в том, что переменную, которую вы передаете как параметр out
, не нужно инициализировать, но передавая ее как параметр ref
, она должна быть установлена на что-то.
int x;
Foo(out x); // OK
int y;
Foo(ref y); // Error: y should be initialized before calling the method
ref
параметры для данных, которые могут быть изменены, out
параметры для данных, которые являются дополнительным выходом для функции (например, int.TryParse
), которые уже используют возвращаемое значение для чего-то.
Ответ 2
Почему у С# есть как 'ref', так и 'out'?
Вызывающий метод, который принимает параметр out, не требуется назначать переменной, переданной как параметр out перед вызовом; однако, вызываемый должен назначить параметр out перед возвратом.
В противоположность, параметры ref считаются первоначально назначенными вызывающим. Таким образом, вызываемому не требуется назначать параметр ref перед использованием. Параметры параметров передаются как в метод, так и вне его.
Итак, out
означает, а ref
- для входа и выхода.
Они тесно соответствуют параметрам [out]
и [in,out]
интерфейсов COM, преимущества параметров out
состоят в том, что вызывающим абонентам не нужно передавать предварительно выделенный объект в случаях, когда он не нужен вызываемым методом - это позволяет избежать как стоимости распределения, так и любых затрат, которые могут быть связаны с маршалингом (более вероятно, с COM, но не редкостью в .NET).
Ответ 3
ref
и out
оба позволяют вызываемому методу изменять параметр. Разница между ними - это то, что происходит до того, как вы сделаете звонок.
-
ref
означает, что параметр имеет значение на нем до, входящее в функцию. Вызываемая функция может читать и/или изменять значение в любое время. Параметр входит, затем выходит -
out
означает, что перед входом в функцию этот параметр не имеет официального значения. Вызываемая функция должна инициализировать его. Параметр выходит только
Здесь мой любимый способ взглянуть на него: ref
- передать переменные по ссылке. out
- объявить вторичное возвращаемое значение для функции. Как будто вы могли бы написать это:
// This is not C#
public (bool, string) GetWebThing(string name, ref Buffer paramBuffer);
// This is C#
public bool GetWebThing(string name, ref Buffer paramBuffer, out string actualUrl);
Здесь приведен более подробный список эффектов каждой альтернативы:
Перед вызовом метода:
ref
: вызывающий должен установить значение параметра перед передачей его вызываемому методу.
out
: метод вызова не требуется устанавливать значение аргумента перед вызовом метода. Скорее всего, вы не должны. Фактически любое текущее значение отбрасывается.
Во время вызова:
ref
: вызываемый метод может прочитать аргумент в любое время.
out
: вызываемый метод должен инициализировать параметр перед его чтением.
Удаленные вызовы:
ref
: текущее значение привязано к удаленному вызову. Дополнительные эксплуатационные расходы.
out
: ничто не передается удаленному вызову. Быстрее.
С технической точки зрения, вместо out
можно использовать ref
, но out
позволяет более точно рассказать о значении аргумента, и иногда это может быть намного более эффективным.
Ответ 4
Пример для OUT: переменная получает значение, инициализированное после входа в метод. Позже это же значение возвращается в метод main.
namespace outreftry
{
class outref
{
static void Main(string[] args)
{
yyy a = new yyy(); ;
// u can try giving int i=100 but is useless as that value is not passed into
// the method. Only variable goes into the method and gets changed its
// value and comes out.
int i;
a.abc(out i);
System.Console.WriteLine(i);
}
}
class yyy
{
public void abc(out int i)
{
i = 10;
}
}
}
Выход:
10
===============================================
Пример для Ref: переменная должна быть инициализирована перед входом в метод. Позднее то же значение или измененное значение будет возвращено основному методу.
namespace outreftry
{
class outref
{
static void Main(string[] args)
{
yyy a = new yyy(); ;
int i = 0;
a.abc(ref i);
System.Console.WriteLine(i);
}
}
class yyy
{
public void abc(ref int i)
{
System.Console.WriteLine(i);
i = 10;
}
}
}
Выход:
0 10
=================================
Надеюсь, теперь все ясно.
Ответ 5
- Перед тем, как передать его, необходимо инициализировать переменную A
ref
. - В реализации вашей функции должна быть указана переменная
out
. -
out
параметры могут рассматриваться как дополнительные возвращаемые переменные (не вводятся) -
ref
параметры могут рассматриваться как как входные, так и выходные переменные.
Ответ 6
Параметры Ref и Out:
Параметры out
и ref
используются для возврата значений в той же переменной, которые вы передаете в качестве аргумента метода. Эти оба параметра очень полезны, когда ваш метод должен возвращать более одного значения.
Вы должны назначить значение для параметра out в кубе метода calee, иначе метод не будет скомпилирован.
Параметр Ref: Он должен быть инициализирован перед тем, как перейти к методу. Ключевое слово
ref
в параметре метода заставляет метод ссылаться на ту же переменную, которая была передана в качестве входного параметра для того же метода. Если вы внесете какие-либо изменения в переменную, они будут отражены в переменной.int sampleData = 0; sampleMethod(ref sampleData);
Пример параметра Ref
public static void Main()
{
int i = 3; // Variable need to be initialized
sampleMethod(ref i );
}
public static void sampleMethod(ref int sampleData)
{
sampleData++;
}
Исходный параметр: Не нужно инициализироваться перед тем, как перейти к методу. Параметр
out
может использоваться для возврата значений в той же переменной, которые передаются как параметр метода. Любые изменения, внесенные в параметр, будут отражены в переменной.int sampleData; sampleMethod(out sampleData);
Ex out Out
public static void Main()
{
int i, j; // Variable need not be initialized
sampleMethod(out i, out j);
}
public static int sampleMethod(out int sampleData1, out int sampleData2)
{
sampleData1 = 10;
sampleData2 = 20;
return 0;
}
Ответ 7
из
В С# метод может возвращать только одно значение. Если вы хотите вернуть более одного значения, вы можете использовать ключевое слово out. Модификатор out возвращается как обратная ссылка. Самый простой ответ заключается в том, что ключевое слово "out" используется для получения значения из метода.
- Вам не нужно инициализировать значение в вызывающей функции.
- Вы должны назначить значение в вызываемой функции, иначе компилятор сообщит об ошибке.
исй:
В С#, когда вы передаете тип значения, такой как int, float, double и т.д. в качестве аргумента параметра метода, он передается по значению. Поэтому, если вы изменяете значение параметра, это не влияет на аргумент в вызове метода. Но если вы отметите параметр ключевым словом "ref", он будет отображаться в фактической переменной.
- Вам нужно инициализировать переменную до вызова функции.
- Не обязательно назначать какое-либо значение параметру ref в методе. Если вы не изменяете значение, в чем состоит необходимость отметить его как "ref"?
Ответ 8
Параметры параметра не требуются для установки в функции, тогда как перед выходом из функции параметры должны быть привязаны к значению. Переменные, передаваемые как входящие, также могут быть переданы функции без инициализации.
Ответ 9
out
указывает, что параметр является выходным параметром, то есть он не имеет значения, пока он не будет явно установлен методом.
ref
указывает, что значение является ссылкой, которая имеет значение и значение которого вы можете изменить внутри метода.
Ответ 10
out
параметры инициализируются методом, который называется, ref
параметры инициализируются перед вызовом метода. Поэтому параметры out
используются, когда вам просто нужно получить вторичное возвращаемое значение, параметры ref
используются для получения значения и, возможно, возвращают изменение к этому значению (во-вторых, к основному возвращаемому значению).
Ответ 11
Ключевое слово ref используется для передачи значений по ссылке. (Это не исключает, что переданные значения являются типами значений или ссылочными типами). Выходные параметры, указанные с ключевым словом out, предназначены для возврата значений из метода.
Одним из ключевых отличий в коде является то, что вы должны установить значение выходного параметра в этом методе. Это не относится к параметрам ref.
Подробнее см. http://www.blackwasp.co.uk/CSharpMethodParameters.aspx
Ответ 12
Параметр out
- это параметр ref
со специальным атрибутом Out()
. Если параметр для метода С# объявлен как out
, компилятор потребует, чтобы этот параметр был записан до того, как он может быть прочитан, и до того, как метод сможет вернуться. Если С# вызывает метод, параметр которого включает атрибут Out()
, компилятор будет в целях принятия решения о том, следует ли сообщать об ошибках "undefined variable", притвориться, что переменная записывается непосредственно перед вызовом метода. Обратите внимание, что, поскольку другие языки .net не добавляют то же значение к атрибуту Out()
, возможно, что вызов подпрограммы с параметром out
оставит указанную переменную незатронутой. Если переменная используется как параметр out
до того, как она определенно назначена, компилятор С# сгенерирует код, чтобы убедиться, что он очищается в какой-то момент до его использования, но если такая переменная уходит и возвращается в область видимости, не гарантируйте, что он будет очищен снова.
Ответ 13
ref, вероятно, захлестнет нуль, поскольку он предположительно ожидает изменения существующего объекта. out ожидает null, так как он возвращает новый объект.
Ответ 14
Этот Вывод и ref Paramerter в С# содержит несколько хороших примеров.
Основное отличие состоит в том, что параметры out
не обязательно должны быть инициализированы при передаче, в то время как параметры ref делают.
Ответ 15
out и ref являются точно такими же, за исключением того, что переменные не нужно инициализировать перед отправкой в бездну. Я не настолько умный, я обрезал это из библиотеки MSDN:).
Однако, чтобы быть более явным в отношении их использования, значение модификатора заключается в том, что если вы измените ссылку на эту переменную в своем коде, out и ref вызовет изменение вашей вызывающей переменной. В приведенном ниже коде переменная ceo будет ссылкой на newGuy, как только она вернется с вызова на doStuff. Если бы не ref (или out), ссылка не была бы изменена.private void newEmployee()
{
Person ceo = Person.FindCEO();
doStuff(ref ceo);
}
private void doStuff(ref Person employee)
{
Person newGuy = new Person();
employee = newGuy;
}
Ответ 16
Когда параметр out объявляется в объявлении метода, тело метода должно назначить значение переменной out перед возвратом. Таким образом, ответственность вызываемого метода присваивает значение параметру out перед его возвратом.
Когда параметр ref объявлен в методе, аргумент, передаваемый при вызове метода, должен присвоить значение. Таким образом, ответственность вызывающего объекта перед назначением метода назначить значение для аргумента ref.
Ответ 17
Они немного отличаются друг от друга.
Параметр out
не должен быть инициализирован вызываемым пользователем перед передачей методу. Поэтому любой метод с параметром out
- Невозможно прочитать параметр перед назначением ему значения
- Обязательно присвойте ему значение перед возвратом
Это используется для метода, который должен перезаписывать свой аргумент независимо от его предыдущего значения.
Параметр
A ref
должен быть инициализирован вызываемым пользователем, прежде чем передать его методу. Поэтому любой метод с параметром ref
- Можно проверить значение перед его назначением
- Может вернуть исходное значение, нетронутое
Это используется для метода, который должен (например,) проверять его значение и проверять его или нормализовать.
Ответ 18
out получил новый синтаксис succint в С# 7 https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#more-expression-bodied-members и еще более увлекательным является усовершенствование кортежей С# 7, которое является более элегантным выбором, чем использование ref и out IMHO.