2012-12-20 109 views
6

我有什麼是簡單的開關語句變量的初始化問題

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

在這種情況下,編譯器告訴我,

局部變量myControl可能無法訪問

之前被初始化

那麼,避免這種情況的最好方法是什麼?

一個選項是在switch語句之前初始化myControl。但在這種情況下,我再做一次不必要的初始化。

CASE 1:

Control myControl = null; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    case TabType.View: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

下一個選項是改變第二殼體與default。之後,編譯器將「理解」myControl將被初始化並且不會拋出異常。

案例2:

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    { 
     myControl= ...; 
    } 

    default: 
    { 

     myControl= ...; 
    } 
} 

myPageView.Controls.Add(myControl); 

但這種情況並沒有看起來那麼好,是因爲增加了一些新特性,以我的枚舉後它將爲所有其他類型的默認參數進行(開發者可以很容易忘了改代碼在這裏,或者不需要爲其他枚舉類型初始化myControl)。

在這種情況下最好的方法是什麼?

+0

編譯器給你答案只是將它設置爲null本地你的錯誤「變量myControl可能在訪問前未初始化」 – MethodMan

回答

5

您的代碼示例表明您將始終在切換塊後使用myControl變量。如果是這種情況,那麼您應該預先初始化變量,或者添加default子句(如您所述)。

如果您擔心可能引入新的枚舉值,那麼您可以在default子句中引發一個有意義的異常。這樣可以防止您在稍後嘗試解除引用該變量時出現更模糊的NullReferenceException

+2

當'default'情況下是拋出異常時+1擊中。也是一個很好的選擇。 –

+1

感謝大家:)拋出有意義的異常的默認子句是不錯的方法。 –

+0

Chuck Norris可以安全地引用Null引用而不會收到NullReferenceException – user93353

3

第三種選擇:

Control mycontrol = null; 
switch (x){ 
    // ... 
} 
if (myControl != null){ 
    // add to controls list, manipulate, etc. 
} 

您還可以添加default:落空的情況下到default(TabType)值:

switch (x){ 
    case TabType.Two: 
    // ... 
    case TabType.Three: 
    // ... 
    case TabType.One: 
    default: 
    // .. 
} 
驗證一個實例進行得(而不是依賴於它被分配)之前創建的
+1

你的第二個例子是他的第二個例子。 – Servy

+1

@ServyL是的,但我已經明確聲明,而不是免除'default(Tabtype)'的值,只是使用'default:'。 –

+0

@DJKRAZE錯字,修正。 – Servy

2

我認爲default專門針對這些情況而存在。

增加了一些新的特性,以我的枚舉它將爲所有其他類型做默認

它可以讓你的代碼在默認的前提下工作(拋出一個異常或設置爲一個衆所周知的值),因此您的代碼也適用於以前沒有計劃的情況。

當然,當你實現新的屬性並期望代碼有不同的行爲時,省略更新這個開關將是一個容易被發現的錯誤。

0

你必須做兩個選項之一;要麼在switch之前指定初始值,要麼添加default大小寫,以便編譯器確定知道switch將初始化該變量。

我會建議,如果交換機不初始化變量可能你只是想拋出一個異常。在這種情況下,只需將該代碼添加到default的情況。通過這種方式,在開發人員忘記爲新的枚舉值添加case而不是僅僅默默無聞地工作時,測試就很清楚。

1

我做一件不必要的initalization

我也不喜歡這樣。

就像很多人已經說過的,爲您的switch聲明添加額外的default:部分。就像這樣:

Control myControl; 
switch(x) 
{ 
    case TabType.Edit: 
    myControl= ...; 
    break; 

    case TabType.View: 
    myControl= ...; 
    break; 

    default: 
    throw new Exception("Unexpected value of x: " + x);   
} 

myPageView.Controls.Add(myControl); 

這是因爲從你的問題,我們知道,您知道x總會有這兩個值中的一個。編譯器不知道這一點。上面的代碼會告訴它。