9

这对我来说似乎是一个错误......

我接受这样定义的自动属性:

public decimal? Total { get; set; }

首次访问时将为空。它们还没有被初始化,所以它们当然是空的。

但是,即使在通过 += 设置它们的值之后,这个小数呢?仍然为空。所以之后:

Total += 8;

总计仍为空。这怎么可能是正确的?我知道它正在执行(null + 8),但似乎很奇怪它没有发现这意味着它应该设置为 8...

附录:

我在我的问题中提出了“null + 8”点 - 但请注意它适用于字符串。因此,它执行 null + "hello" 就好了,并返回 "hello"。因此,在幕后,它是将字符串初始化为值为“hello”的字符串对象。其他类型 IMO 的行为应该相同。可能是因为字符串可以接受 null 作为值,但 null 字符串仍然不是初始化对象,对吗?

也许这只是因为字符串不是可空的......

4

10 回答 10

31
public decimal? Total { get; set; }

null其视为“未知值”。如果你有一个未知数量的东西,然后再添加 8 个,你现在有多少?

答:未知。

可空变量的操作

某些情况下,对未知值的操作会为您提供可知的结果。

public bool? State { get; set; }

即使它们包含未知值,以下语句也有已知的解决方案:

State = null;
nextState = State & false;         // always equals false
nextState = State & true;          // still unknown (null)

nextState = State | true;          // always true
nextState = State | false;         // still unknown (null)

看到图案了吗?

当然,如果你 Total在它是 的时候等价(等于)0 null,你可以使用空合并操作符,这样写:

Total = (Total ?? 0) + 8;

这将使用Total方程中的值,除非它是null,在这种情况下它将使用值 0。

于 2009-08-26T15:01:53.727 回答
7
Null + 8 = Null

您需要先将其设置为零。

于 2009-08-26T14:53:42.133 回答
5

null表示未知值,

unknown value + known value = still unknown value
于 2009-08-26T14:53:51.650 回答
3

这是一个在第一次调用时初始化它并在之后增加它的单行代码:

    public void InitializeOrIncrement(decimal value)
    {
        // if Total is null then initialize, otherwise increment
        Total = (Total == null) ? value : Total + value;
    }

    public decimal? Total { get; set; }
于 2009-08-26T15:01:27.207 回答
2

来自MSDN

当您对可空类型执行比较时,如果其中一个可空类型的值为 null 而另一个不是,则所有比较的结果都为 false,但 !=(不等于)除外。重要的是不要假设因为特定的比较返回 false,相反的情况返回 true。

因此,它按预期工作。

于 2009-08-26T14:55:37.963 回答
1

我知道这样做很有意义

public decimal? Total { get; set; }

Total = (Total ?? 0) + 8;

但这样做会不会更容易:

public decimal Total { get; set; }

Total 的初始值为 0

于 2009-08-26T15:46:03.360 回答
1

正如其他人指出的那样, null 不等于零。尽管从长远来看,将空整数默认为零似乎更方便,但它可能会产生奇怪的结果,直到为时已晚才发现。

举个简单的例子,假设您的一个数据馈送失败并使用空值填充您的结果集。您的计算会将空值视为零并继续产生结果。由于数字仍在出现,即使它们可能是错误的,您也可能永远不会注意到出现严重错误。

于 2010-04-13T09:53:26.663 回答
0

设置 Total 的值只是

Total = 8;

我建议阅读Nullable Types以了解它们是如何工作的。您可以使用 来检查属性是否具有值HasValue

来自MSDN

运营商

可空类型也可以使用预定义的一元和二元运算符以及为值类型存在的任何用户定义的运算符。如果操作数为空,则这些运算符产生空值;否则,操作员使用包含的值来计算结果。例如:

int? a = 10;
int? b = null;

a++;         // Increment by 1, now a is 11.
a = a * 10;  // Multiply by 10, now a is 110.
a = a + b;   // Add b, now a is null.
于 2009-08-26T14:55:18.120 回答
0

Null 与零不同。零加八等于八……但零加八?始终为空。就像无穷大加上任何东西仍然是无穷大 - 它是未定义的。

你会发现这对于 null 是普遍适用的。每个数据库(至少我曾经使用过的)都会给你相同的结果。

于 2009-08-26T15:04:25.627 回答
0

公共小数?总{得到; 放; }

像这样的东西会起作用吗?如果尚未设置值,则进行某种自动初始化。

public decimal? Total
{
  get { return this.totalValue;}
  set
  { 
     if(totalValue == null) { this.totalValue = 0;}
     this.totalValue = value;
  }
}

private decimal? totalValue;
于 2009-08-26T15:04:50.523 回答