Почему методы 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
?
Ответы
Ответ 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, что было бы отвратительно избыточным.