9

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

Stepping through the code showing the value of amount3

Watch dialog and some more detail about state of variables

13
  • CurrencyTextBox (a subclass of TextBox) Commented Aug 14, 2012 at 21:09
  • 1
    It's a nullable decimal [decimal?] - see the getter/setter definition at the top of the question Commented Aug 14, 2012 at 21:13
  • 1
    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? Because when XXX is a nullable decimal, then XXX ?? 0M will be a (non-nullable) decimal that will have the value of XXX if that is non-null, and the value zero otherwise. Commented Aug 14, 2012 at 21:18
  • I can't really reproduce this, possibly an issue with when Text is updated. Or indeed a debugger artifact. Commented Aug 14, 2012 at 21:21
  • 2
    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 I'm sure that without the debugger, the value will be updated exactly when you expect it. Commented Aug 14, 2012 at 21:37

2 Answers 2

1

(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?

Sign up to request clarification or add additional context in comments.

Comments

1

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.

3 Comments

Turns out, it's a debugger issue. I was very concerned that my use of ?? had a lot of unknown side effects and I'd have to go over all my projects and ensure I changed syntax
Also, .Value is decimal? (Nullable<decimal>)
oh I didnt make that connection, since its a nullable decimal the actual value would be Value.Value :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.