Что лучше, возвращаемое значение или выходной параметр? - PullRequest
138 голосов
/ 01 мая 2009

Если мы хотим получить значение из метода, мы можем использовать любое возвращаемое значение, например:

public int GetValue(); 

или

public void GetValue(out int x);

Я не очень понимаю разницу между ними, и поэтому не знаю, что лучше. Ты можешь мне это объяснить?

Спасибо.

Ответы [ 17 ]

1 голос
/ 01 мая 2009

Оба они имеют различное назначение и не обрабатываются одинаково компилятором. Если ваш метод должен вернуть значение, вы должны использовать return. Out используется, когда ваш метод должен возвращать несколько значений.

Если вы используете return, то данные сначала записываются в стек методов, а затем в вызывающий метод. Хотя в случае out он напрямую записывается в стек вызывающих методов. Не уверен, есть ли еще различия.

1 голос
/ 01 мая 2009

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

Однако есть некоторые незначительные различия, но ни один из них не является действительно важным:

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

int n;
GetValue(n);

при использовании возвращаемого значения позволит вам сделать это в одну строку:

int n = GetValue();

Другое отличие (верно только для типов значений и только в том случае, если C # не включает функцию), в том, что использование возвращаемого значения обязательно создаст копию значения, когда функция, возвращаемая при использовании параметра OUT, не обязательно сделает это.

1 голос
/ 21 сентября 2017

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

var result = DoThing();
if (result.Success)
{
    result = DoOtherThing()
    if (result.Success)
    {
        result = DoFinalThing()
        if (result.Success)
        {
            success = true;
        }
    }
}

против

var result;
if (DoThing(out result))
{
    if (DoOtherThing(out result))
    {
        if (DoFinalThing(out result))
        {
            success = true;
        }
    }
}
1 голос
/ 07 апреля 2017

Кроме того, возвращаемые значения совместимы с парадигмами асинхронного проектирования.

Нельзя назначить функцию «асинхронная», если она использует параметры ref или out.

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

0 голосов
/ 28 ноября 2018

Я подозреваю, что я не собираюсь заглядывать в этот вопрос, но я очень опытный программист, и я надеюсь, что некоторые из более открытых читателей обратят внимание.

Я считаю, что он лучше подходит для объектно-ориентированных языков программирования, поскольку их процедуры возврата значений (VRP) являются детерминированными и чистыми.

«VRP» - это современное академическое название для функции, которая вызывается как часть выражения и имеет возвращаемое значение, которое условно заменяет вызов во время вычисления выражения. Например. в таком выражении, как x = 1 + f(y), функция f служит в качестве VRP.

«Детерминистический» означает, что результат функции зависит только от значений ее параметров. Если вы вызовете его снова с теми же значениями параметров, вы обязательно получите тот же результат.

«Чистый» означает отсутствие побочных эффектов: вызов функции ничего не делает , за исключением вычисления результата. На практике это может быть истолковано как означающее отсутствие важных побочных эффектов, поэтому, если VRP выводит сообщение отладки каждый раз, когда оно вызывается, например, это, вероятно, можно игнорировать.

Таким образом, если в C # ваша функция не является детерминированной и чистой, я говорю, что вы должны сделать ее функцией void (другими словами, не VRP), и любое значение, которое она должна вернуть, должно быть возвращено в либо out, либо ref параметр.

Например, если у вас есть функция для удаления некоторых строк из таблицы базы данных, и вы хотите, чтобы она возвращала количество удаленных строк, вы должны объявить ее примерно так:

public void DeleteBasketItems(BasketItemCategory category, out int count);

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

Возможно, вы захотите узнать , почему этот стиль лучше подходит для объектно-ориентированного программирования. В целом, он вписывается в стиль программирования, который можно (немного неточно) назвать «процедурным программированием», и это стиль процедурного программирования, который лучше подходит для объектно-ориентированного программирования.

Почему? Классическая модель объектов состоит в том, что они имеют свойства (или атрибуты), и вы запрашиваете и манипулируете объектом (главным образом) путем чтения и обновления этих свойств. Стиль процедурного программирования облегчает эту задачу, поскольку вы можете выполнять произвольный код между операциями, которые получают и устанавливают свойства.

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

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

0 голосов
/ 30 марта 2017

возвращаемое значение - это нормальное значение, которое возвращается вашим методом.

Где в качестве параметра out , well out и ref являются 2 ключевыми словами C #, они позволяют передавать переменные как reference .

Большая разница между ref и out заключается в том, что ref следует инициализировать до и out не

0 голосов
/ 08 декабря 2016

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

Пример

public BookList Find(string key)
{
   BookList book; //BookList is a model class
   _books.TryGetValue(key, out book) //_books is a concurrent dictionary
                                     //TryGetValue gets an item with matching key and returns it into book.
   return book;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...