2010-02-18 73 views
2

我有下面的代碼:一次幾個未分配的局部變量?

static void Main(string[] args) 
    { 
    byte currency; 
    decimal amount; 
    if (Byte.TryParse("string1", out currency) && Decimal.TryParse("string2", out amount)) 
    { 
     Check(currency, amount); 
    } 
    Check(currency, amount); // error's here 
    } 

    static void Check(byte b, decimal d) { } 

,並得到一個錯誤:

Use of unassigned local variable 'amount'

爲什麼我會得到它在所有,這是合法的,爲什麼只爲amount?爲什麼currency在這種情況下分配和amount - 不是?

+0

請參閱此問題的其他信息:http://stackoverflow.com/questions/1542824/c-initialization-of-instance-fields-vs-local-variables – M4N 2010-02-18 22:59:46

回答

2

看這句話(我已經分開成兩行):

if (Byte.TryParse("string1", out currency) && 
    Decimal.TryParse("string2", out amount)) 

&&運營商一個短路評估,這意味着如果第一個Byte.TryParse不成功,那麼第二個Decimal.TryParse將永遠不會被執行。

currency將始終分配,因爲TryParseout currency設置爲默認值(如果解析失敗)。但是,在這種情況下,amount仍未定義。就好像你編寫了這樣的代碼:

if (Byte.TryParse("string1", out currency)) 
{ 
    if (Decimal.TryParse("string2", out amount)) 
    { 
     Check(currency, amount); 
    } 
} 
Check(currency, amount); 

這應該使它更明顯發生了什麼。第一個if語句中的部分總是被執行併爲currency賦值。 第二個,嵌套if語句中的部分只會在第一個成功執行時纔會執行。否則,amount到第二個Check時沒有任何價值。

如果要使用默認值,如果currency不能被解析,那麼就初始化當地人爲默認值:

byte currency = 0; 
decimal amount = 0; 
if (Byte.TryParse("string1", out currency) && 
    Decimal.TryParse("string2", out amount)) 
{ 
// Etc. 

或者你可以簡單地解析他們兩個,作爲@馬丁說過。

0

發生這種情況是因爲程序中存在一個路徑,編譯器無法保證amount被賦予一個初始值:第一個TryParse()失敗時。這就是爲什麼你會在你嘗試使用amount時發現錯誤。

From MSDN:

甲作爲out參數傳遞變量不需要被初始化。但是,在方法返回之前,必須爲out參數分配一個值。

你可以通過你的本地變量分配默認值解決它:

decimal amount = 0; 

否則你必須確保兩個TryParse()調用在任何情況下進行,例如(不是真的漂亮的代碼):

bool b1 = Byte.TryParse("string1", out currency); 
bool b2 = Decimal.TryParse("string2", out amount); 

if (b1 && b2) {...} 

順便說一句:這個代碼片段也將產生相同的編譯器錯誤,因爲a未分配的值:

int a, b=1; 
int c = a+b; 
+0

@Martin:默認情況下,Struts獲取它的值,isn'它呢? – abatishchev 2010-02-18 22:08:35

+0

@Martin:我認爲運行時不會失敗,只能在IDE中作爲警告。兩個TryParse調用都會失敗,那麼爲什麼警告只顯示小數點,而不是字節? – 2010-02-18 22:11:51

+0

@Rick Mogstad:這是一個錯誤事件,不只是一個警告。 – abatishchev 2010-02-18 22:13:56

1

這只是一個編譯器警告,旨在阻止您使用未分配的變量(儘管我認爲您明白這一點)。我無法解釋爲什麼你只有在使用其中一個未賦值的變量時纔會得到它。

1

C#語言規範的第5.3章對此進行了討論。這是一個很有意思的章節,但它肯定會讓我看到編譯器也應該爲未分配的「貨幣」變量發出一個錯誤。如果你註釋掉if()語句和塊,它會變得很有趣,現在編譯器突然冒出來了。即使「貨幣」從未在評論代碼中使用過。

這是不對的,我認爲你發現了一個錯誤。如果埃裏克利珀不路過,你可以在connect.microsoft.com報告錯誤

+2

這不是一個錯誤。第一個'TryParse'將總是被執行並將out arg設置爲默認值;如果第一個失敗,第二個'TryParse'不會被執行,所以'amount'的值可能是未定義的,但'currency'的值不會。 – Aaronaught 2010-02-18 22:54:22

+0

糟糕,你是對的。我沒有看到使用不同輸出參數的TryParse調用。 – 2010-02-19 00:05:43

+1

如果您想要引起我的注意,可以使用我博客上的聯繫人鏈接。 – 2010-02-21 16:12:56