




ref, вероятно, задохнется на null, поскольку он предположительно ожидает изменения существующего объекта. out ожидает null, поскольку возвращает новый объект.
Foo (ref null) не компилируется, но строка bar = null; Foo (ref bar); Это хорошо.
Подавиться нулевой константой? Как Джеймс Карран, вы не можете передавать константу в аргументе ref.
Я не имел в виду нулевую константу: я имел в виду переменную с нулевым значением.
Параметры ссылки не обязательно должны быть установлены в функции, тогда как параметры out должны быть привязаны к значению перед выходом из функции. Переменные, переданные как исходящие, также могут быть переданы в функцию без инициализации.
Параметры out инициализируются вызываемым методом, параметры ref инициализируются перед вызовом метода. Следовательно, параметры out используются, когда вам просто нужно получить вторичное возвращаемое значение, параметры ref используются для получения значения и, потенциально возвращающего изменение этого значения (во вторую очередь основного возвращаемого значения).
Они почти одинаковы - с той лишь разницей, что переменную, которую вы передаете как параметр 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), которые уже используют возвращаемое значение для чего-то.
Кроме того, параметры out должны быть установлены во время выполнения вызываемого перед возвратом к вызывающему, что противоречит ref, который должен быть установлен вызывающим перед вызовом вызываемого.
@Mike Ваше исправление НЕПРАВИЛЬНО. Это было правильно, «и метод, использующий параметр из, должен что-то установить». Метод, получающий параметр out, должен его инициализировать. Метод, получающий параметр ref, может делать с ним все, что хочет. Конечно, он может это игнорировать. Откатываю обратно.
Несомненно, главное отличие состоит в том, что ссылки находятся внутри и снаружи, тогда как out можно использовать только для возврата данных. рассматривать недействительные работы (ref int z) {Debug.WriteLine (z); } и void notWorks (out int z) {Debug.WriteLine (z); } или я упустил какой-то трюк, чтобы получить значение параметра out до его инициализации? Я заметил, что отладчик, например, может это сделать.
Поэтому для параметров, которые должны быть установлены на что-то по пути, следует использовать ref. В противном случае используйте вне.
С другой стороны, ref может спасти дополнительную копию Struct от создания во время вызова функции. С другой стороны, класс может быть инициализирован нулевым значением, поэтому вам ВСЕ ЕЩЕ нужно остерегаться этого.
И еще одно отличие: x (параметр out) ДОЛЖЕН быть присвоено значение в функции foo, а ref МОЖНО присвоить значение в foo.
Этот ответ приуменьшает значение --- и без того тонкого --- различия между ними; это не лучший подход для обучения других.
Почему в C# есть как ref, так и out?
Вызывающий метод, который принимает выходной параметр, не обязан назначать переменную, переданную как выходной параметр перед вызовом; однако перед возвратом вызываемый должен назначить параметр out.
Напротив, параметры ref считаются изначально назначенными вызывающей стороной. Таким образом, вызываемому не требуется назначать параметр ref перед использованием. Параметры ссылки передаются как в метод, так и из него.
Итак, out означает выход, а ref - вход и выход.
Они близко соответствуют параметрам [out] и [in,out] COM-интерфейсов, причем преимущества параметров out заключаются в том, что вызывающим абонентам не нужно передавать предварительно выделенный объект в тех случаях, когда он не нужен вызываемому методу - это позволяет избежать затрат на выделение и выделение ресурсов. и любые затраты, которые могут быть связаны с маршалингом (более вероятно, с COM, но не редко в .NET).
«Напротив, параметры ref считаются изначально назначенными вызываемым пользователем», вы наверняка имели в виду «вызывающий». Я пытался отредактировать ваш ответ, но это не позволяет мне сохранить такое незначительное изменение.
В ссылке есть очень четкое объяснение разницы, лучше, чем большинство ответов здесь. Спасибо!
Ключевое слово ref используется для передачи значений по ссылке. (Это не препятствует тому, чтобы передаваемые значения были типами значений или ссылочными типами). Параметры вывода, указанные с ключевым словом out, предназначены для возврата значений из метода.
Одним из ключевых отличий кода является то, что вы должны установить значение выходного параметра внутри метода. Это не относится к параметрам ref.
Подробнее см. http://www.blackwasp.co.uk/CSharpMethodParameters.aspx
В этом Параметр out and ref в C# есть несколько хороших примеров.
Основное отличие заключается в том, что параметры out не нуждаются в инициализации при передаче, в то время как параметры ref это нужно.
out и ref точно такие же, за исключением того, что переменные out не нужно инициализировать перед отправкой в бездну. Я не такой уж умен, я это скопировал из библиотеки 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;
}
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: удаленному вызову ничего не передается. Быстрее.
Технически говоря, вы всегда можете использовать ref вместо out, но out позволяет вам уточнить смысл аргумента, а иногда это может быть намного эффективнее.
Строка, упомянутая как «Это не C#», теперь на самом деле C#, начиная с C# 7 docs.microsoft.com/en-us/dotnet/csharp/whats-new/…
Пример для OUT: переменная получает значение, инициализированное после входа в метод. Позже это же значение возвращается основному методу.
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;
}
}
}
Output:
10
===============================================
Пример для ссылки: переменная должна быть инициализирована перед переходом к методу. Позже то же значение или измененное значение будет возвращено основному методу.
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;
}
}
}
Output:
0 10
=================================
Надеюсь, теперь все ясно.
ref необходимо инициализировать.out должна быть установлена в вашей реализации функции.out можно рассматривать как дополнительные возвращаемые переменные (не входные)ref можно рассматривать как входные и выходные переменные.out указывает, что параметр является выходным параметром, то есть не имеет значения, пока не будет явно задан методом.
ref указывает, что значение является ссылкой, имеющей значение, значение которой вы можете изменить внутри метода.
Параметры out и ref используются для возврата значений в той же переменной, которую вы передаете в качестве аргумента метода. Оба эти параметра очень полезны, когда ваш метод должен возвращать более одного значения.
Вы должны присвоить значение параметру out в теле метода calee, иначе метод не будет скомпилирован.
Ref Parameter : It has to be initialized before passing to the Method. The
refkeyword on a method parameter causes a method to refer to the same variable that was passed as an input parameter for the same method. If you do any changes to the variable, they will be reflected in the variable.int sampleData = 0; sampleMethod(ref sampleData);
Ex of 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 Parameter : It is not necessary to be initialized before passing to Method. The
outparameter can be used to return the values in the same variable passed as a parameter of the method. Any changes made to the parameter will be reflected in the variable.int sampleData; sampleMethod(out sampleData);
Ex из выходного параметра
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;
}
Параметр out - это параметр ref с добавленным специальным атрибутом Out(). Если параметр метода C# объявлен как out, компилятор потребует, чтобы параметр был записан, прежде чем его можно будет прочитать и до того, как метод сможет вернуться. Если C# вызывает метод, параметр которого включает атрибут Out(), компилятор, чтобы решить, сообщать ли об ошибках «неопределенной переменной», будет делать вид, что переменная записана непосредственно перед вызовом метода. Обратите внимание, что, поскольку другие языки .net не придают такое же значение атрибуту Out(), возможно, что вызов подпрограммы с параметром out не повлияет на рассматриваемую переменную. Если переменная используется в качестве параметра out до того, как она будет определенно назначена, компилятор C# сгенерирует код, чтобы гарантировать, что она будет очищена в какой-то момент перед ее использованием, но если такая переменная покидает и повторно входит в область видимости, нет никаких гарантий что он снова будет очищен.
В C# метод может возвращать только одно значение. Если вы хотите вернуть более одного значения, вы можете использовать ключевое слово out. Модификатор out возвращается как возврат по ссылке. Самый простой ответ - ключевое слово «out» используется для получения значения из метода.
В C#, когда вы передаете тип значения, такой как int, float, double и т. д., В качестве аргумента параметра метода, он передается по значению. Следовательно, если вы измените значение параметра, это не повлияет на аргумент в вызове метода. Но если вы отметите параметр ключевым словом «ref», он отразится в фактической переменной.
Они немного разные.
Параметр out не нужно инициализировать вызываемым пользователем перед передачей в метод. Следовательно, любой метод с параметром out
Это используется для метода, которому необходимо перезаписать свой аргумент независимо от его предыдущего значения.
Параметр ref должен быть инициализирован вызываемым пользователем перед передачей его методу. Следовательно, любой метод с параметром ref
Это используется для метода, который должен (например) проверить свое значение и проверить его или нормализовать.
out получил новый более лаконичный синтаксис в C# 7 https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#more-expression-bodied-members и еще более захватывающим является усовершенствование кортежей C# 7, которое является более элегантным выбором, чем использование ref и out IMHO.
На мой взгляд, это не дубликат упомянутого вопроса, потому что 1. он предшествовал этому вопросу 2. в этом вопросе есть детали, не относящиеся к «дубликату».