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

Почему все перегрузки TryParse имеют параметр out?

Я обнаружил, что много раз мне не нужен параметр out метода TryParse, но проблема в том, что это обязательно. Здесь я покажу один пример, когда это не нужно.

Я хочу проверить, является ли строка целым числом, если это целое число, то выведите "Integer"; в противном случае выведите "Not integer". Итак, вот код:

string value = Console.ReadLine(); //Get a value from the user.
int num; //Why should I have it?? No need at all !

if (int.TryParse(value, out num))
{
    Console.WriteLine("An integer");
}
else
{
    Console.WriteLine("Not an integer");
}

Мне просто интересно, почему TryParse всегда возвращает выходной параметр? Почему у него нет перегрузки без параметра out?

4b9b3361

Ответ 1

Обновленный ответ:

В более поздних версиях С# вы можете объявить выходной параметр как встроенный, что позволяет вам удалить строку кода, которая вам не нужна в вашем примере:

string value = Console.ReadLine(); //Get a value from the user.

if (int.TryParse(value, out int num))
{
    Console.WriteLine("An integer");
}
else
{
    Console.WriteLine("Not an integer");
}

Вы можете просто проигнорировать результат в своем коде и больше не иметь этой дополнительной строки. У вас еще есть дополнительный параметр, но так?

Основное "почему" остается тем же и вряд ли когда-либо изменится. Метод должен был возвращать две вещи: bool указывающий на успех, и int указывающий результирующее значение в случае успеха. (Я не могу придумать другой способ передать результат, не так ли?) Поскольку метод может возвращать только одну вещь, а пользовательский тип результата кажется излишним для этого, было принято решение вернуть bool и получить результат быть out параметром. И как только это решение было принято, оно должно оставаться на время действия языка.

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

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


Оригинальный ответ:

Короткий ответ: "Потому что так определен метод". Возможно, случайно кто-то из команды языков С# может найти этот вопрос и объяснить, почему были приняты решения, но это на самом деле мало что меняет на данный момент. С# - это статически скомпилированный язык, и сигнатуры методов должны соответствовать так, как оно есть.

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

Возможно, вы сможете обойти это в своем собственном коде. Что-то простое, как метод расширения, может помочь вам:

public static bool IsInt(this string s)
{
    int x = 0;
    return int.TryParse(s, out x);
}

Тогда в вашем коде вам просто нужно вызвать этот метод из строкового значения:

string value = Console.ReadLine();
if (value.IsInt())
    Console.WriteLine("An integer");
else
    Console.WriteLine("Not an integer");

Ответ 2

У него есть параметр out, потому что подавляющее большинство времени, когда люди его используют, они хотят, чтобы анализировалось int (или double, или decimal, или datetime, или что-то еще).

Если вы не хотите/нуждаетесь в анализируемом значении, и вы все время делаете это, вы можете написать свою собственную "обертку" на .TryParse(), которая просто берет строку.

В этом примере (и вы можете сделать его более общим, я уверен) вы могли бы сделать что-то вроде

public static bool TryParseNoOutput(this string value)
{
  int noNeed = 0;
  return int.TryParse(value, out noNeed);
}

Затем в вашем коде (в этом случае) вы должны позвонить:

string value = Console.ReadLine();
if(value.TryParseNoOutput()) Console.WriteLine("An Integer");
else Console.WriteLine("Not an integer."):

Изменить: Как было указано в комментариях, я попытался вызвать "int.TryParseNoOutput", когда я определил его как расширение в строке. Ответ был обновлен, чтобы отразить это.

Ответ 3

TryParse - относительно сложная операция для определения представления int a string. Если бы была перегрузка, которая просто возвращает bool, было бы очень вероятно, что многие (неопытные) разработчики последуют этому неэффективному шаблону:

int myInt = -1;
if(int.TryParse("123"))
    myInt = int.Parse("123");

Ответ 4

Почему у TryParse есть параметр out?
По самой простой причине, как TryParse реализован.
Как вы определяете, является ли что-то понятным, это его разбор! Если вы можете что-то разборчиво, тогда это разборчиво. Если вы не можете разобрать его, то это не будет понятно.

Поэтому, чтобы определить, является ли что-то понятным или нет, если оно является синтаксическим, то мы уже проанализировали его! Было бы глупо выбрасывать эту анализируемую ценность (любой, кто задается вопросом о том, что-либо анализируется, скорее всего, интересуется анализируемым результатом), поэтому возвращается значение parsed.

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