Понимание нулевого коалесцирующего оператора (??)
У меня есть пользовательский WebControl
, который реализует .Value
геттер / сеттер, возвращающий Nullable
Это отфильтрованное текстовое поле на стороне клиента (подкласс TextBox
с включенным javascript и некоторой логикой на стороне сервера для установки / получения значения)
Вот геттер и сеттер из этого элемента управления:
public decimal? Value
{
get
{
decimal amount = 0;
if (!decimal.TryParse(this.Text, NumberStyles.Currency, null, out amount))
{
return null;
}
else
{
return amount;
}
}
set
{
if (!value.HasValue)
{
this.Text = "";
}
else
{
this.Text = string.Format("${0:#,##0.00}", value);
}
}
}
Проблема, которую я вижу, заключается в том, что вывод из этого утверждения:
decimal Amount = uxAmount.Value ?? 0M;
Я вижу, что сумма устанавливается в "0", Когда uxAmount.Value
возвращается 10000.
Это сработало, как я и ожидал (извините за изменение в корпусе):
decimal? _Amount = uxAmount.Value;
decimal amount = _Amount ?? 0;
Я также видел это поведение (недавно) при вызове функции UDF, определенной в контексте данных Linq2Sql, вместе с оператором null coalescing, то есть я знал, что мой вызов UDF вернул ожидаемое значение, но вместо этого я получал значение RHS.
Еще больше запутывает меня, если я оцениваю uxAmount.Значение в часах, я получаю 10000 типа Nullable<decimal>
.
Вот некоторые выражения, которые я имел попробовал:
decimal? _Amount = uxAmount.Value; //10000
decimal amount = _Amount ?? 0; //10000
decimal amount2 = _Amount ?? 0M; //10000
decimal Amount = uxAmount.Value ?? 0M; //0
Затем я добавил Это выражение после приведенных выше 4
decimal amount3 = (uxTaxAmount.Value) ?? 0M;
Теперь
decimal Amount = uxAmount.Value ?? 0M; //10000
decimal amount3 = (uxAmount.Value) ?? 0M; //0
Похоже, что последний вызов всегда равен 0, но значение uxAmount.Value
(которое разбирается из .Text
согласно приведенному выше геттеру/сеттеру с использованием TryParse
стабильно. Я остановлен в точке останова, и нет никаких других потоков, которые могли бы манипулировать этим значением.
Есть идеи?
Значение как LHS, так и RHS, по-видимому, является стабильным и известным.-- edit-- некоторые скриншоты из VS2010
2 ответа:
(этот ответ был построен из моих комментариев выше.)
Вы уверены, что отладчик dsiplays это правильно для вас? Вы пробовали перейти на несколько строк ниже, чтобы убедиться, что у вас есть обновленное значение
amount3
?Я уверен, что это просто проблема с отладчиком. Иногда приходится идти чуть дальше. Может быть, переведенный код (IL) имеет некоторые оптимизации, которые сбивают с толку отладчик (или что бы я знал). Но без отладчика значение будет обновлено точно когда вы этого ожидаете.
Я видел, как другие опытные разработчики были сбиты с толку подобными ситуациями, поэтому я знаю, что отладчик иногда "на одну строку кода" отстает, когда смотрит на назначение локальной переменной. Может быть, кто-нибудь найдет ссылку, обсуждающую это?
Взгляните на этот аналогичный вопрос
Используя срастанию нулевой оператор на типы, допускающие значение null изменения неявного типа
Почему бы просто не сделать
decimal amount = uxTaxAmount.Value.HasValue ? uxTaxAmount.Value.Value : 0M
Это не правильный ответ на проблемы с оригинальными плакатами, учитывая недавние правки и комментарии.