I have a custom WebControl
which implements a .Value
getter/setter returning a Nullable<decimal>
It's a client-side filtered textbox (a subclass of TextBox
with included javascript and some server side logic for setting/getting the value)
Here is the getter & the setter from that control:
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);
}
}
}
The problem that I'm seeing is that the output from this statement:
decimal Amount = uxAmount.Value ?? 0M;
I am seeing Amount being set to "0" when uxAmount.Value
returns 10000.
This worked as I expected (excuse the change in casing):
decimal? _Amount = uxAmount.Value;
decimal amount = _Amount ?? 0;
I have also seen this behaviour (recently) when calling a UDF function defined on a Linq2Sql data context along with the null coalescing operator, that is I knew my UDF call returned the expected value but I was getting the RHS value instead.
Further confusing me, if I evaluate uxAmount.Value in the watch, I get 10000 of type Nullable<decimal>
.
Here are some expressions I've tried:
decimal? _Amount = uxAmount.Value; //10000
decimal amount = _Amount ?? 0; //10000
decimal amount2 = _Amount ?? 0M; //10000
decimal Amount = uxAmount.Value ?? 0M; //0
Then I added this expression following the above 4
decimal amount3 = (uxTaxAmount.Value) ?? 0M;
Now
decimal Amount = uxAmount.Value ?? 0M; //10000
decimal amount3 = (uxAmount.Value) ?? 0M; //0
It seems like the last call is always 0, but the value of uxAmount.Value
(which is parsed out of .Text
as per above getter/setter using a TryParse
is stable. I'm stopped at a breakpoint and there's no other threads that could manipulate this value.
Note the use of the M suffix to force the constant to decimal as it was integer and I suspected a type conversion issue.
Any ideas?
The value of both the LHS and RHS appear to be stable and known.
--edit-- some screengrabs from VS2010
The nullish coalescing operator ( ?? ) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined , and otherwise returns its left-hand side operand.
Null-coalescing Operator Use this operator to fall back on a given value. In cases where a statement could return null, the null-coalescing operator can be used to ensure a reasonable value gets returned. This code returns the name of an item or the default name if the item is null.
The name "Elvis operator" refers to the fact that when its common notation, ?: , is viewed sideways, it resembles an emoticon of Elvis Presley with his signature hairstyle.
A null-conditional operator applies a member access, ?. , or element access, ?[] , operation to its operand only if that operand evaluates to non-null; otherwise, it returns null . That is, If a evaluates to null , the result of a?. x or a?[x] is null .
(This answer was constructed from my comments above.)
Are you sure the debugger dsiplays this correctly to you? Have you tried stepping some lines further down to make sure you have the updated value of amount3
?
I'm sure it's just an issue with the debugger. Sometimes you have to step a little further. Maybe the translated code (IL) has some optimizations that confuse the debugger (or what would I know). But without the debugger, the value will be updated exactly when you expect it.
I've seen other experienced developers being confused by similar situations, so I know the debugger sometimes is "one line of code" behind when looking at an assignment to a local variable. Maybe someone can find a link discussing that?
Take a look at this similar question
using coalescing null operator on nullable types changes implicit type
why not just do
decimal amount = uxTaxAmount.Value.HasValue ? uxTaxAmount.Value.Value : 0M
This isn't the right answer to the original posters problems given recent edits and comments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With