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

Почему методы TryParse используют параметр out, а не ref

В некоторой степени в этом вопросе , который задает вопрос о поведении параметра out, но более сфокусирован на том, почему эти методы TryParse используют out а не ref.

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

Этот сценарий может выглядеть так...

int arg = 123;
Int32.TryParse(someString, ref arg);

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

int arg;
if(!Int32.TryParse(someString, out arg)
{
    arg = 123;
}

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

Итак, почему эти методы TryParse используют out, а не ref?

4b9b3361

Ответ 1

Потому что нормальный шаблон использования точно противоположен тому, что вы описываете.

Люди должны иметь возможность писать

int arg;
if (!Int32.TryParse(someString, ref arg)) {
    Waaah;
}

Если TryParse принял параметр ref, для этого потребовалась бы бесполезная инициализация.

Реальный вопрос заключается в том, почему не существует метода int? int.TryParse(string).

Ответ 2

Вы используете out, чтобы указать, что параметр не используется, только установлен. Вызывающему требуется, чтобы назначить значение перед возвратом метода:

int n;
if (Int32.TryParse("47", out n)) { // Works fine; `n` will be set to the
  // ..                            // result of the parse.
}

Если вы использовали ref, вам нужно было бы инициализировать значение заранее, что глупо, так как оно все равно будет перезаписано:

int n;
if (Int32.TryParse("47", ref n)) { // Kablammo! `n` isn't initialized.
  // ..
}

Это точно точка TryParse: вы гарантированно получите значение в параметре out, который представляет результат попытки разбора. Возвращаемое значение true или false указывает, следует ли вам заботиться о результате или игнорировать его.

Ответ 3

Это потому, что параметр out лучше подходит для того, что делает этот метод.

Если он использовал параметр ref, то вы должны указать ввод метода. Это не сработало бы:

int arg;
if (Int32.TryParse(someString, ref arg)) { // error - variable is not initialsed

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

Ответ 4

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

Вопрос хороший, и я не думаю, что существует серьезная проблема, использующая один подход или другой. Команда .NET выбрала подход, поскольку они не могли использовать оба без добавления отдельного метода к int, что было бы отвратительно избыточным.