Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
623 views
in Technique[技术] by (71.8m points)

c# - Understanding the null coalescing operator (??)

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...