关于c#:理解null合并运算符(??)

Understanding the null coalescing operator (??)

我有一个自定义的WebControl,它实现了一个.Valuegetter/setter,返回一个可以为空的

它是一个客户端过滤文本框(TextBox的子类,包含javascript和一些用于设置/获取值的服务器端逻辑)

下面是该控件的getter和setter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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);
        }
    }
}

我看到的问题是这个语句的输出:

1
decimal Amount = uxAmount.Value ?? 0M;

uxAmount.Value返回10000时,我看到金额被设置为"0"。

如我所料(请原谅套管的变化):

1
2
decimal? _Amount = uxAmount.Value;
decimal amount = _Amount ?? 0;

在调用Linq2SQL数据上下文上定义的UDF函数以及空合并运算符时(最近),我也看到了这种行为,也就是说,我知道我的UDF调用返回了预期值,但我得到的是rhs值。

更让我困惑的是,如果我在表中评估uxAmount.value,我会得到10000个Nullable类型的值。

以下是我尝试过的一些表达方式:

1
2
3
4
decimal? _Amount = uxAmount.Value; //10000
decimal amount = _Amount ?? 0; //10000
decimal amount2 = _Amount ?? 0M; //10000
decimal Amount = uxAmount.Value ?? 0M; //0

然后我在上面的4后面添加了这个表达式

1
decimal amount3 = (uxTaxAmount.Value) ?? 0M;

现在

1
2
decimal Amount = uxAmount.Value ?? 0M; //10000
decimal amount3 = (uxAmount.Value) ?? 0M; //0

最后一个调用似乎总是0,但是根据上面的getter/setter,使用TryParse.Text中解析出来的uxAmount.Value的值是稳定的。我在一个断点处被停止,没有其他线程可以操纵这个值。

注意使用m后缀强制常量为十进制,因为它是整数,我怀疑是类型转换问题。

有什么想法吗?

左舵驾驶和右舵驾驶的价值似乎是稳定和已知的。

--编辑——从VS2010中截取一些屏幕

Stepping through the code showing the value of amount3

Watch dialog and some more detail about state of variables


(这个答案是根据我上面的评论构建的。)

您确定调试器会正确地向您发送这个消息吗?你有没有试着更进一步,以确保你有更新的amount3值?

我相信这只是调试程序的问题。有时候你得再往前走一步。也许翻译后的代码(IL)有一些优化会混淆调试器(或者我知道什么)。但是如果没有调试程序,值将在您期望的时候被更新。

我见过其他有经验的开发人员对类似的情况感到困惑,所以我知道当查看对局部变量的赋值时,调试器有时是"一行代码"。也许有人能找到一个链接讨论这个?


看看这个类似的问题

对可为空的类型使用合并的空运算符将更改隐式类型

为什么不只是做

1
decimal amount = uxTaxAmount.Value.HasValue ? uxTaxAmount.Value.Value : 0M

鉴于最近的编辑和评论,这不是对原始海报问题的正确答案。