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

agr*_*ath 9 c# nullable null-coalescing-operator

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

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

这是来自该控件的getter和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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

decimal Amount = uxAmount.Value ?? 0M;
Run Code Online (Sandbox Code Playgroud)

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

这符合我的预期(原则是套管的变化):

decimal? _Amount = uxAmount.Value;
decimal amount = _Amount ?? 0;
Run Code Online (Sandbox Code Playgroud)

我也看到了这种行为(最近)在调用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
Run Code Online (Sandbox Code Playgroud)

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

decimal amount3 = (uxTaxAmount.Value) ?? 0M;
Run Code Online (Sandbox Code Playgroud)

现在

decimal Amount = uxAmount.Value ?? 0M; //10000
decimal amount3 = (uxAmount.Value) ?? 0M; //0
Run Code Online (Sandbox Code Playgroud)

似乎最后一次调用总是为0,但是uxAmount.Value(.Text使用a TryParse得到的getter/setter 解析出来的值是稳定的.我在断点处停止并且没有其他线程可以操纵这个值.

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

有任何想法吗?

LHS和RHS的值似乎都是稳定且已知的.

--edit--来自VS2010的一些屏幕抓片

单步执行显示amount3值的代码

观察对话框以及有关变量状态的更多详细信息

Jep*_*sen 1

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

您确定调试器能正确地向您显示此内容吗?您是否尝试过进一步降低一些行以确保您拥有 的更新值amount3

我确信这只是调试器的问题。有时你必须走得更远一些。也许翻译后的代码(IL)有一些优化让调试器感到困惑(或者我知道什么)。但如果没有调试器,该值将在您期望的时间准确更新。

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