2012-01-27 103 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#中執行此操作。
相關問題