理解空合并运算符(??)

时间:2012-08-14 21:06:04

标签: c# nullable null-coalescing-operator

我有一个自定义WebControl,它实现了一个.Value getter / setter,返回一个Nullable< decimal>

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

这是吸气剂和放大器来自该控件的setter:

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);
        }
    }
}

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

decimal Amount = uxAmount.Value ?? 0M;

uxAmount.Value返回10000时,我看到Amount被设置为“0”。

这就像我预期的那样(原则上改变套管):

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

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

进一步让我感到困惑,如果我在手表中评估uxAmount.Value,我会得到10000 Nullable<decimal>类型。

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

decimal? _Amount = uxAmount.Value; //10000
decimal amount = _Amount ?? 0; //10000
decimal amount2 = _Amount ?? 0M; //10000
decimal Amount = uxAmount.Value ?? 0M; //0

然后我按照上面的4

添加了这个表达式
decimal amount3 = (uxTaxAmount.Value) ?? 0M;

现在

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

似乎最后一次调用始终为0,但uxAmount.Value的值(使用.Text按照上面的getter / setter从TryParse解析出来的值是稳定的.I我停在断点处,没有其他线程可以操纵这个值。

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

有什么想法吗?

LHS和RHS的值似乎都很稳定且已知。

- 编辑 - 来自VS2010的一些屏幕抓取

Stepping through the code showing the value of amount3

Watch dialog and some more detail about state of variables

2 个答案:

答案 0 :(得分:1)

看看这个类似的问题

using coalescing null operator on nullable types changes implicit type

为什么不做呢

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

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

答案 1 :(得分:1)

(这个答案来自我上面的评论。)

你确定调试器能正确地解决这个问题吗?您是否尝试过进一步下行以确保您具有amount3的更新值?

我确定这只是调试器的一个问题。有时你需要更进一步。也许翻译的代码(IL)有一些优化混淆调试器(或我知道什么)。但是没有调试器,该值将在您预期时准确更新。

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