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

Любая проблема, объявляющая переменную и использующая TryParse для ее инициализации в одной строке?

Этот пример находится в С#, но я ожидаю, что это применимо и к другим так же легко.

Недавно я обнаружил, что следующее выглядит просто отлично:

int i = Int32.TryParse(SomeString, out i) ? i : -1;

Как-то кажется, что переменная i не должна технически быть доступна в точке, которая появляется в TryParse. Или я был бы прав, если предположить, что int i эффективно объявляет переменную, хотя еще нет конца инструкции?

4b9b3361

Ответ 1

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

Тем не менее, есть мои коллеги, которые могли бы пригодиться, увидев что-то подобное по стилю.: -)

РЕДАКТИРОВАТЬ: После того, как мы рассмотрим, как это сотряслось, я предложу несколько возможных альтернативных вспомогательных методов. Именование статического класса действует как документация намерений для вспомогательных методов здесь.

internal static class TryConvert
{
    /// <summary>
    /// Returns the integer result of parsing a string, or null.
    /// </summary>
    internal static int? ToNullableInt32(string toParse)
    {
        int result;
        if (Int32.TryParse(toParse, out result)) return result;
        return null;
    }

    /// <summary>
    /// Returns the integer result of parsing a string,
    /// or the supplied failure value if the parse fails.
    /// </summary>
    internal static int ToInt32(string toParse, int toReturnOnFailure)
    {
        // The nullable-result method sets up for a coalesce operator.
        return ToNullableInt32(toParse) ?? toReturnOnFailure;
    }
}

internal static class CallingCode
{
    internal static void Example(string someString)
    {
        // Name your poison. :-)
        int i = TryConvert.ToInt32(someString, -1);
        int j = TryConvert.ToNullableInt32(someString) ?? -1;

        // This avoids the issue of a sentinel value.
        int? k = TryConvert.ToNullableInt32(someString);
        if (k.HasValue)
        {
            // do something
        }
    }
}

Ответ 2

Недавно я обнаружил, что следующее выглядит просто отлично

 int i = Int32.TryParse(SomeString, out i) ? i : -1;

Это работает, но это не нормально.

Любая проблема, объявляющая переменную и использующая TryParse для ее инициализации в той же строке?

Да, читаемость. Я думаю, что это выглядит ужасно, и он делает двойную работу.


Часть вашей проблемы состоит в том, что вы хотите, чтобы -1 был по умолчанию. Int32.TryParse явно определяет 0 как значение out, когда преобразование завершается с ошибкой.

Я бы все равно разбил его на две строки для удобства чтения.

int i;
if (! int.TryParse(SomeString, out i))  i = -1;

И когда вам это нужно много, напишите вспомогательный метод (статический, но не внутренний):

int i = Utils.ParseInt(SomeString, -1);

Ответ 3

Помните, что в CIL нет тройного оператора.

int i = Int32.TryParse(SomeString, out i) ? i : -1;

Ваш код преобразуется в CIL, представляющий следующий код С#:

int i;
if (Int32.TryParse(SomeString, out i))
  i = i;
else
  i = -1;

Это прекрасно.