Understanding the null coalescing operator (??)

人盡茶涼 提交于 2019-11-28 03:14:53

问题


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


回答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?




回答2:


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.



来源:https://stackoverflow.com/questions/11960732/understanding-the-null-coalescing-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!