2012-01-27 107 views
7

我有这样的特性:未设置时,属性是否总是有值?

public Tuple<String, String>[] Breadcrumbs { get; set; } 

,我在这样的我的方法之一,有一个测试:

if (Breadcrumbs != null && Breadcrumbs.Length > 0) { } 

根据当这个方法被调用,Breadcrumbs可能没有被设置。在一次测试中,Breadcrumbs == null的结果为真。

未设置的属性总会有值吗? (它会始终是null?)

回答

18

未由任何代码明确设置的自动实现的属性将始终具有属性类型的默认值 - 对于引用类型为null。 (对于int它将是0,对于char它将是'\ 0'等)。

一个这样的自动实现的属性是只是等同于:

private PropertyType property; 
public PropertyType Property 
{ 
    get { return property; } 
    set { property = value; } 
} 

...除了后盾变量有一种难言的名称(您不能引用它的代码),所以它会总是从类型的默认值开始。

+2

+1为“难以形容的名字”:) – 2012-01-27 15:17:56

3

自动属性使用后备字段并编译为常规属性。

如果属性类型是引用类型,则值将为空,如果不是,则该值将是默认值。

2

如果未明确初始化类成员变量(称为字段),并且因此属性的支持变量始终被初始化为其默认值(对于引用类型而言为null)。所有类型的默认值是其二进制表示由所有位设置为0的值组成。

另一方面,C#要求您明确初始化局部变量。它们是:在方法,构造函数和属性访问器中声明的变量以及方法参数;即它们被视为未定义,直到您为其分配一个值。

+0

哎呀,我一直在编码C#直到现在,我的印象是,我必须初始化所有东西或冒险找到大量的随机垃圾。我想我会保持这种习惯,所以当我回到C时,我不会犯这些非常微妙的错误之一。 – Oliver 2012-01-27 14:46:29

+0

C#编译器能够很好地检测可能未初始化的变量,所以不要太担心! – 2012-01-27 14:52:22

+2

@奥利弗:不,你永远不会发现随机垃圾;内存管理器总是初始化它。 (在安全的代码中;在不安全的代码中,你是独立的,这就是为什么它被称为“不安全”的原因。)但是,C#确实需要你在读取之前明确地初始化所有局部变量;这不是为了防止你看到垃圾,而是为了防止你写错误。 – 2012-01-27 15:12:07

0

它在逻辑上不可能没有价值。它将不得不返回一些东西,一些1和0的组合,至少被认为是对Tuple<String, String>[]的引用,所以在这个程度上它具有价值。

这也是在类中的所有字段将会设置为默认值(default(T)因为他们是什么类型T,这是null所有引用类型)的情况下。否则,就有可能让一个对象处于一种状态,这种状态不仅对它所做的事情没有任何意义,而且对于.NET期望的对象的规则没有任何意义。这包括自动属性后面的隐藏字段。

现在,在一些语言中,我们可以做这样的等价物:

public Tuple<String, String>[] Breadcrumbs 
{ 
    get 
    { 
    Tuple<String, String>[] whatIWillSend; 
    return whatIWillSend; 
    } 
} 

如果被允许,whatIWillSend必须由您的任何Concious酒店决定不定义的值,但发生的事情是在当时的记忆中。它可能为空,它可能是巧合的有效的Tuple<String, String>[](但不是你想要使用的那个!),它可能是运行时现在认为的Dictionary<int, List<string>>实际上是Tuple<String, String>[](这是整个系统的类型安全性),它可能是decimal结构的四分之一。 (在允许这样的事情的语言中,它也可能是一个众所周知的价值,即这些语言的调试器在这些情况下设置的恰恰是帮助找到由它引起的错误)。

这是我们可以找到的物业没有价值的最接近的东西。请注意:

  1. 它仍然有一个值,只是没有意义的价值。
  2. 无论如何,我们不允许在C#中执行此操作。
相关问题