В каком ситуации отсутствуют полезные параметры (где 'касательно' не мог использоваться вместо этого)?

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

Так есть ли другие ситуации где out параметры могли оказаться полезными и где мы не могли использовать ref параметры вместо этого?

Спасибо.

18
задан stakx supports GoFundMonica 28 August 2011 в 12:02
поделиться

6 ответов

Да - разница между ref и out заключается в определенном назначении:

  • Параметр out не должен быть определенно назначен вызывающей стороной перед вызовом метода. Он действительно должен быть определенно назначен в методе, прежде чем он вернется нормально (то есть без исключения).Затем переменная определенно назначается в вызывающем после вызова.

  • Параметр ref действительно должен быть определенно назначен вызывающей стороной перед вызовом метода. Ему не нужно назначать другое значение в методе.

Предположим, мы хотим изменить int.TryParse (string, out int) , чтобы использовать вместо него ref . Обычно вызывающий код выглядит так:

int value;
if (int.TryParse(text, out value))
{
    // Use value
}
else
{
    // Do something else
}

Теперь, если бы мы использовали ref , нам пришлось бы дать value значение перед вызовом, например:

int value = 0;
if (int.TryParse(text, ref value))
{
    // Use value
}
else
{
    // Do something else
}

Очевидно, это не огромная разница, но она производит неправильное впечатление. Мы присваиваем значение, которое не собираемся когда-либо использовать, и это плохо для читабельности. Параметр out указывает, что значение будет выходить из метода (при условии отсутствия исключения) и что вам не нужно иметь значение для начала.

Одно из предложений, которые я сделал для C # 5 (я понятия не имею, будут ли они приняты), заключается в том, что метод с параметром out можно рассматривать как метод, возвращающий кортеж значений. В сочетании с улучшенной поддержкой кортежей это означало бы, что мы могли бы сделать что-то вроде этого:

var (ok, value) = int.TryParse(text);

В этом случае ok и value будут неявно типизированы как bool и int соответственно. Таким образом становится ясно, что входит в метод ( текст ) и что выходит (две части информации: ok и значение ).

Это было бы просто недоступно, если бы int.TryParse использовал вместо этого параметр ref - поскольку компилятор не может знать, будет ли он на самом деле заботиться о начальном значении параметра ref .

29
ответ дан 30 November 2019 в 06:46
поделиться

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

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

(Для параметра ref это не требуется)

Источник: http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.71).aspx

4
ответ дан 30 November 2019 в 06:46
поделиться

Вы можете рассматривать параметры таким образом:

  • обычные параметры - это in параметры:
    Значение может войти в функцию через такой параметр; поэтому он должен быть инициализирован.

  • ref параметры - это in-out параметры:
    Через такой параметр значение может войти в функцию и выйти из нее. Из-за первого он также должен быть инициализирован.

  • out параметры - out параметры:
    Значение должно возвращаться из функции только через такой параметр; поэтому его не нужно инициализировать.

Я пришел к такому взгляду на ref/out параметры, изучая технологию COM компании Microsoft. IDL (язык описания интерфейсов) используется для описания интерфейсов компонентов COM, а в IDL параметры дополняются деклараторами in, out и inout. Я подозреваю, что .NET и C# частично унаследовали эти деклараторы от COM, хотя и с немного другими именами (ref вместо inout).

В COM параметры out часто используются для получения фактического возвращаемого значения метода интерфейса, поскольку "реальное" возвращаемое значение часто уже используется для возврата кода успеха/ошибки HRESULT.

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

8
ответ дан 30 November 2019 в 06:46
поделиться

Параметр out полезен, когда вы хотите получить несколько значений результата из метода. Технически вы можете использовать параметр ref для достижения той же цели, но параметр out значительно лучше передает намерение. Когда вы используете ref , непонятно, почему вы делаете это вместо использования out или вместо использования результата функции. Предположительно, вы намереваетесь изменить переданное значение, но почему вы меняете его, неясно просто из сигнатуры функции.

2
ответ дан 30 November 2019 в 06:46
поделиться

Я думаю, что прекрасный пример - int.TryParse ()

http://msdn.microsoft.com/en-us/library/f02979c7.aspx

Основная причина того, что out лучше, чем ref , состоит в том, что вам не нужно назначать фиктивное значение возвращаемой переменной перед вызовом (даже неявно).

Итак, out сообщает вам и компилятору: «Эта переменная будет назначена в методе. И начальное значение переменной, если оно есть, даже не будет рассматриваться».

2
ответ дан 30 November 2019 в 06:46
поделиться

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

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

0
ответ дан 30 November 2019 в 06:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: