简体   繁体   English

C#自动属性 ​​- + =后仍为空?

[英]C# Automatic Properties - Still null after +=?

This seems like a bug to me... 这对我来说似乎是个错误......

I accept that automatic properties, defined as such: 我接受自动属性,定义如下:

public decimal? Total { get; set; }

Will be null when they are first accessed. 首次访问时将为null。 They haven't been initialized, so of course they are null. 它们尚未初始化,因此它们当然是空的。

But, even after setting their value through +=, this decimal? 但是,即使在通过+ =设置它们的值之后,这个十进制? still remains null. 仍然是空的。 So after: 之后:

Total += 8;

Total is still null. 总计仍为空。 How can this be correct? 这怎么可能是正确的? I understand that it's doing a (null + 8), but seems strange that it doesn't pick up that it means it should just be set to 8... 我知道它正在做一个(null + 8),但似乎很奇怪,它没有拿起它意味着它应该只被设置为8 ...

Addendums: 补遗:

I made the "null + 8" point in my question - but notice that it works with strings. 我在我的问题中提出了“null + 8” - 但请注意它适用于字符串。 So, it does null + "hello" just fine, and returns "hello". 所以,它确实为null +“hello”就好了,并返回“hello”。 Therefore, behind the scenes, it is initializing the string to a string object with the value of "hello". 因此,在幕后,它将字符串初始化为值为“hello”的字符串对象。 The behavior should be the same for the other types, IMO. 对于其他类型,IMO,行为应该是相同的。 It might be because a string can accept a null as a value, but still, a null string is not an initialized object, correct? 这可能是因为字符串可以接受null作为值,但是,空字符串仍然不是初始化对象,对吗?

Perhaps it's just because a string isn't a nullable... 也许这只是因为一个字符串不是可以为空的......

public decimal? Total { get; set; }

Think of null as "unknown value". null视为“未知值”。 If you have an unknown quantity of something and you add 8 more, how many do you have now? 如果你有一个未知数量的东西,你又增加了8个,你现在有多少?

Answer: unknown. 答:未知。

Operations on Nullable Variables 可空变量的操作

There are cases where operations on unknown values give you knowable results. 某些情况下,对未知值的操作会为您提供可知的结果。

public bool? State { get; set; }

The following statements have knowable solutions even though they contain unknown values: 以下语句具有可知的解决方案,即使它们包含未知值:

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)

See the pattern? 看模式?

Of course, if you want Total to be equivalent (equal) to 0 when it is null , you can use the null coalescing operator and write something like this: 当然,如果你希望 Totalnull时等于(等于)0,你可以使用null coalescing运算符并写下这样的东西:

Total = (Total ?? 0) + 8;

That will use the value of Total in your equation unless it is null , in which case it will use the value 0. 除非它是null否则它将在等式中使用Total null ,在这种情况下,它将使用值0。

Null + 8 = Null

您需要先将其设置为零。

null表示未知值,

unknown value + known value = still unknown value

Here's a one-liner to initialize it on the first call and increment it afterwards: 这是在第一次调用时初始化它并在之后增加它的单行:

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

    public decimal? Total { get; set; }

From MSDN : 来自MSDN

When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal). 当您使用可空类型进行比较时,如果其中一个可空类型的值为null而另一个不是,则除了!=(不等于)之外,所有比较都会计算为false。 It is important not to assume that because a particular comparison returns false, the opposite case returns true. 重要的是不要假设因为特定比较返回false,相反的情况返回true。

So, it works as intended. 所以,它按预期工作。

I know that it makes sense to do 我知道这样做很有意义

public decimal? Total { get; set; }

Total = (Total ?? 0) + 8;

but wouldnt it just be easier to do : 但它不会更容易做到:

public decimal Total { get; set; }

initial value of Total is 0 Total的初始值为0

As other people have pointed out, null is not equal to zero. 正如其他人所指出的,null不等于零。 Although it may seem more convenient for a null integer to default to zero in the long run it is likely to produce weird results that you may not spot until it is too late. 虽然从长远来看,空整数默认为零似乎更方便,但可能会产生奇怪的结果,直到为时已晚,您可能无法发现。

As a quick example, say one of your data feeds fails and populates your result set with nulls. 作为一个简单的例子,假设您的一个数据源失败并使用空值填充结果集。 Your calculations will treat the nulls as zeros and continue to produce results . 您的计算会将空值视为零并继续生成结果 As numbers are still coming out, even though they are likely wrong, you might never notice that something has gone critically wrong. 由于数字仍然存在,即使它们可能是错误的,你也许永远不会注意到某些事情已经出现严重错误。

to set the value of the Total is just 设置Total的值就是

Total = 8;

I would recommend reading up on Nullable Types to understand how they work. 我建议阅读Nullable Types以了解它们的工作原理。 You can check to see if the property has a value by using HasValue . 您可以使用HasValue检查属性是否具有值。

From MSDN : 来自MSDN

Operators 运营商

The predefined unary and binary operators and any user-defined operators that exist for value types may also be used by nullable types. 预定义的一元和二元运算符以及值类型存在的任何用户定义的运算符也可以由可空类型使用。 These operators produce a null value if the operands are null; 如果操作数为null,则这些运算符产生空值; otherwise, the operator uses the contained value to calculate the result. 否则,运算符使用包含的值来计算结果。 For example: 例如:

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.

Null isn't the same as zero. Null与零不同。 Zero plus eight is eight... but null plus eight? 零加八是八......但是零加八? Always null. 始终为空。 Just like infinity plus anything is still infinity - it's undefined. 就像无限加上任何东西仍然是无限的 - 它是未定义的。

You'll find that this is universally true of null. 你会发现这普遍适用于null。 Every database (at least that I've ever worked with) will give you the same result. 每个数据库(至少我曾经使用过的数据库)都会给你相同的结果。

public decimal? 公共小数? Total { get; 总计{得到; set; 组; } }

Would something like this work? 会这样的吗? Some sort of automatic initalization if the value isn't yet set. 如果尚未设置值,则进行某种自动初始化。

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

private decimal? totalValue;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM