Использование переменной в качестве аргумента out в точке объявления
При чтении comment в ответ я увидел следующую конструкцию для объявления и инициализации переменной:
int variable = int.TryParse(stringValue, out variable) ? variable : 0;
Это разрешено, правильно и четко определено в С#?
Что происходит под капотом? Что происходит?
- Изначально
variable
инициализируется до нуля?
- затем передается в
int.TryParse
(который присваивает значение)?
- затем, возможно, прочитайте (если
int.TryParse
return true
)?
- а затем, снова назначенный/инициализированный?
Ответы
Ответ 1
Это трюк, который срабатывает, потому что это просто переписывание обычного оператора if. Этот код эквивалентен этому:
int variable;
if (int.TryParse(stringVariable, out variable))
variable = variable;
else
variable = 0;
Последовательность выглядит следующим образом:
int.TryParse
, variable
не инициализируется до этого, но ему также не нужно. Параметр out
не требует определенной назначенной переменной. Как часть выполнения метода, variable
получит значение, а int.TryParse
вернет true
или false
.
Если метод возвращает true
, тогда результат выражения будет variable
и, следовательно, мы будем выполнять в основном variable = variable
.
Если метод возвращает false
, тогда результат выражения будет 0
, а variable
теперь будет иметь значение 0
, независимо от того, что оно было дано как часть int.TryParse
. В этом случае, однако, это не изменит переменную, поскольку int.TryParse
уже присвоило variable
значение по умолчанию, когда оно возвращает false
, которое также оказывается 0
.
Это в основном способ получить все на одной строке.
Лично я бы написал этот код следующим образом:
int variable;
int.TryParse(stringValue, out variable);
Ответ 2
Да, вы правы для исполнения. Вы также можете посмотреть здесь созданные MSIL.
Код С#
string stringValue = "5";
int variable = int.TryParse(stringValue, out variable) ? variable : 0;
Созданный MSIL
1. IL_0000: nop
2. IL_0001: ldstr "5" // load string
3. IL_0006: stloc.0
4. IL_0007: ldloc.0
5. IL_0008: ldloca.s variable
6. IL_000a: call bool [mscorlib]System.Int32::TryParse(string, int32&)
7. IL_000f: brtrue.s IL_0014
8. IL_0011: ldc.i4.0
9. IL_0012: br.s IL_0015
10. IL_0014: ldloc.1
11. IL_0015: stloc.1
12. IL_0016: ret
Что разъясняет, что он делает за сценой.
Ведомость 5 выделяет переменную в стек.
Вызов 6 вызывает метод.
Заявление 7,8,9 фактически exeuting выражение bool.
Ответ 3
int variable
объявляет variable
, а out variable
обязательно инициализирует его. Обе эти вещи должны произойти до того, как variable
используется где угодно, и из-за объявления out
это верно.
Как указал Лассе В. Карлсен, из документации TryParse, TryParse
по умолчанию назначит ему значение 0
, если преобразование не выполняется:
Когда этот метод возвращается, [ return
] содержит 32-разрядное знаковое целочисленное значение, эквивалентное числу, содержащемуся в s, если преобразование выполнено успешно, или ноль, если преобразование завершилось с ошибкой. (emph мой)
Если вы выберете тройную функцию, вы увидите:
int variable;
if (int.TryParse(stringValue, out variable))
variable = variable;
else
variable = 0;
который сам по себе является юридическим выражением. Два пути:
-
TryParse
присваивает значение variable
и возвращает true, что приводит к присваиванию variable
самому себе
-
TryParse
инициализирует variable
до 0
и возвращает false, что приводит к присваиванию variable
как нуля по тернарному условию
Это не совсем четкий код, и я бы не рекомендовал его делать.
Ответ 4
Я не открыл Visual Studio, чтобы попробовать, но да, это разрешено.
Все зависит от переменной "stringValue". Если это можно разделить на целое число, int.TryParse
вернет true, а [variable] будет иметь целочисленное значение. Если нет, то variable
будет установлено в 0.
Это делает для читаемого кода? Видимо, нет.