Подтвердить что ты не робот

Какова действительная причина использования параметра "out" или "ref" в методе?

Я презираю и исправляю параметры для методов. ИМХО, они делают код менее чистым и предоставляют возможности для побочных эффектов. Но я признаю, что я не понимаю их полезности, которая могла бы объяснить часть моего ненависти. Пожалуйста, может кто-нибудь объяснить действительный случай для выхода или ссылки?

4b9b3361

Ответ 1

В принципе, если вам нужно вернуть более одного значения, это альтернатива использованию чего-то типа Tuple<,> или настраиваемого типа для инкапсуляции значений. Канонический пример, вероятно, int.TryParse и связанные с ним методы. Они хотят передать две части информации:

  • Проанализированное значение
  • Успешно ли синтаксический анализ.

Теперь они могли быть написаны с использованием типа возврата int? и т.д. в этом случае, но это тот же принцип для других случаев. (Например, Dictionary<,>.TryGetValue, где значение, хранящееся в словаре, может иметь законное значение.)

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

Ответ 2

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

Обратите внимание, что вы можете мутировать объект, даже если объявлен без ref (при условии, что он изменен в первую очередь, конечно).

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

Ответ 3

В "новом" (С# 4.0) lock используется ref (технически оператор lock является синтаксическим сахаром для нового Monitor.Enter перегрузка). Без него было бы невозможно: -)

bool acquiredLock = false;

try
{
    Monitor.Enter(lockObject, ref acquiredLock);

    // Code that accesses resources that are protected by the lock.

}
finally
{
    if (acquiredLock)
    {
        Monitor.Exit(lockObject);
    }
}

поэтому в очень критичных местах есть место для ref.

Причина, по которой просто возврат значения bool будет недостаточной, заключается в том, что между return true Monitor.Enter и bool acquiredLock = может возникнуть исключение, оставляя вашу программу с вопросом "была ли блокировка лишена?". С параметром ref эта проблема решена.

Ответ 4

Они почти одинаковы - единственное отличие состоит в том, что переменную, которую вы передаете как параметр out, не нужно инициализировать, а метод с использованием параметра out должен установить его на что-то.

int x;
Foo(out x); 

int y;
Foo(ref y); 

Ref параметры для данных, которые могут быть изменены, out параметры для данных, которые являются дополнительным выходом для функции (например, int.TryParse), которые уже используют возвращаемое значение для чего-то.