C # параметры вывода и возврат

Итак, я новичок в C #, и мне трудно понять out. В отличие от простого возврата чего-либо из функции

using System;
class ReturnTest
{
    static double CalculateArea()
    {
         double r=5;
         double area = r * r * Math.PI;
         return area;
    }

    static void Main()
    {
         double output = CalculateArea();
         Console.WriteLine("The area is {0:0.00}", output);
    } 
 }

сравните с этим

 using System;
 class ReturnTest
 {
     static void CalculateArea(out double r)
     {
         r=5;
         r= r * r * Math.PI;
     }

     static void Main()
     {
         double radius;
         CalculateArea(out radius);
         Console.WriteLine("The area is {0:0.00}",radius );
         Console.ReadLine();
     }
}

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

Однако есть ли разница между операторами out и return, как показано выше? Есть ли причина отдавать предпочтение тому или другому с точки зрения синтаксиса?


person Frank Visaggio    schedule 26.06.2012    source источник
comment
Изучите Dictionary.TryGetValue и int.TryParse и посмотрите, объясняют ли эти примеры полезность out.   -  person Kirk Woll    schedule 26.06.2012
comment
out в основном используется, когда вам нужно вернуть несколько несвязанных значений из метода. Кроме того, он часто используется для имитации указателей при взаимодействии с машинным кодом через COM или p / invoke.   -  person dlev    schedule 26.06.2012
comment
Помните, что в C / C ++ есть указатели. Когда вы передаете указатель в функцию, вы можете изменить его внутри функции, и значение также изменится в вызывающей функции. out делает примерно то же самое.   -  person carny666    schedule 26.06.2012
comment
@ carny666: Я думаю, что ref больше похож на ссылки C ++, чем на out.   -  person Tudor    schedule 26.06.2012
comment
@KirkWoll, это два отличных примера, спасибо!   -  person Frank Visaggio    schedule 26.06.2012
comment
возможный дубликат Что лучше: возвращаемое значение или выходной параметр?   -  person nawfal    schedule 15.01.2014


Ответы (5)


Хорошее использование out вместо return для получения результата - это шаблон Try, который вы можете увидеть в определенных API, например Int32.TryParse(...). В этом шаблоне возвращаемое значение используется, чтобы сигнализировать об успехе или неудаче операции (в отличие от исключения), а параметр out используется для возврата фактического результата.

Одно из преимуществ Int32.Parse - скорость, поскольку исключений можно избежать. Некоторые тесты были представлены в этом другом вопросе: Производительность парсинга (если, TryParse, Try-Catch )

person Tudor    schedule 26.06.2012

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

Примером является метод Int32.TryParse, который имеет как возвращаемое значение (логическое значение, представляющее успех попытки), так и параметр out, который получает значение, если синтаксический анализ был успешным.

Метод может возвращать объект, содержащий как логическое, так и целое число, но для этого потребуется создать объект в куче, что снизит производительность метода.

person Guffa    schedule 26.06.2012
comment
Мне также интересно узнать о разнице в производительности (если есть). Исходя из среды C ++, аргумент состоит в том, что копирование объекта, возвращаемого по значению, обходится дороже. Верно ли это и для C #? Я имею в виду, если вы создадите новый массивный объект внутри функции и вернете его, будет ли он скопирован во все, что вы назначаете? В отличие от создания объекта и его изменения с помощью ключевого слова out? Или это неактуально в C #? - person Reasurria; 21.05.2015
comment
@Reasurria: если вы создаете объект и возвращаете его, возвращается только ссылка, объекты не клонируются. В .NET объекты клонируются только в том случае, если вы специально клонируете их, передача объектов не создает новых копий. - person Guffa; 21.05.2015

Я использую out только тогда, когда мне нужно несколько вещей, возвращаемых одним методом. Out позволяет избежать объединения нескольких объектов в класс для возврата. Посмотрите пример на странице Microsoft Out .

person Coeffect    schedule 26.06.2012
comment
Обратите внимание, что в последних версиях C # теперь это можно делать с помощью кортежей значений. Например (имя строки, возраст int) GetMultipleValues ​​() {return (james, 31); } - person Damien Sawyer; 20.07.2018

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

person Rob H    schedule 26.06.2012

Когда речь идет об одной переменной, и возврат в порядке. Но что, если вы хотите вернуть более одного значения? Out помогает в этом.

static void CalculateArea(out double r, out double Foo)
{
    //Can return 2 values in terms of out variables.
}

static double CalculateArea(double r)
{
     // Will return only one value.
}
person Nikhil Agrawal    schedule 26.06.2012