2015-09-20 79 views
0

UGH!那麼我要張貼這個問題,因爲我不知道爲什麼我看到了錯誤...但當然,現在它是如此明顯,當我看到它。現在把自己拍在頭上。儘管如此,我仍然會把它留在這裏。看看你能否抓住它。爲什麼這個方法有一個'out'參數表示它沒有設置?

在今晚爲WeakDictionary類實現TryGetValue時,我遇到了一些奇怪的事情。我收到一個錯誤,我不知道爲什麼。

下面的代碼:

public bool TryGetValue(TKey key, out TItem value) 
{ 
    WeakReference<TItem> weakReference; 

    if(_itemStorage.TryGetValue(key, out weakReference)) 
     if(weakReference.TryGetTarget(out value)) 
      return true; 
    else 
     value = default(TItem); 

    return false; 
} 

這裏是我得到的錯誤:

的輸出參數「價值」必須被分配到控制離開當前方法之前。

對我來說,它看起來像所有代碼路徑設置「值」它返回之前。

如果第一個'if'失敗,'else'從句設置'value'。

但是,如果第一個'if'通過,不過下一行'weakReference.TryGetTarget'設置'value'的原因與我被警告的原因完全相同(即'TryGetTarget'有'out'參數本身,因此它也必須在返回之前在內部設置它的參數)?

就像我說的,我錯過了一些明顯的東西。 (我需要睡覺!)

+0

在一天結束時,這實際上只是一個簡單的錯字。說一下總是使用大括號首選項(和自動代碼縮進),但這就是我使用它們的原因。 – user2864740

+0

我剛剛在Visual Studio的多個版本中嘗試過這種方法,它正確縮進了'else'語句,與第二個'if'語句保持一致,顯然它屬於那個。你在使用另一個IDE嗎? –

+0

是的,但是那個簡單的錯字讓我在一個半小時的時間裏讓我失去了研究,因爲我打了我的額頭,意識到我是個白癡! :) – MarqueIV

回答

7

問題在於,如果您的第一個if語句失敗,您將留下未初始化的值。

基本上,你錯過了你的if語句花括號,這將使else說法正確安裝到正確的if

if (_itemStorage.TryGetValue(key, out weakReference)) 
{ 
    if (weakReference.TryGetTarget(out value)) 
     return true; 
} 

The docs明確了這一點:

聲明或else語句中的語句可以是任何類型的,包括嵌套在原始if語句內的另一個if語句 。在嵌套if語句中,每個 else子句都屬於最後一個,如果沒有對應的其他 。

這意味着,你的else條款被安裝到內if聲明,而不是outter。

您也可以重新寫爲:

public bool TryGetValue(TKey key, out TItem value) 
{ 
    WeakReference<TItem> weakReference; 

    if (_itemStorage.TryGetValue(key, out weakReference)) 
     return weakReference.TryGetTarget(out value); 

    value = default(TItem); 
    return false; 
} 
+0

省略大括號並沒有在示例代碼中有所作爲,因爲每個條件語句後跟一個語句。 –

+1

@SaebAmini嘗試一下,看看。 –

+0

第一個,我在我的答案中有一個。如果兩個if語句都通過,第二個會重複設置'value'兩次。 –

4

取出else聲明。

與@Yuval的回答一樣有效,但我喜歡刪除代碼。

public bool TryGetValue(TKey key, out TItem value) 
{ 
    WeakReference<TItem> weakReference; 

    if(_itemStorage.TryGetValue(key, out weakReference)) 
    if(weakReference.TryGetTarget(out value)) 
     return true; 

    value = default(TItem); 

    return false; 
} 

還要注意的是if(c1) if(c2)相當於if (c1 && c2);它讀得更好,不會有你的問題。

2

您的代碼被編譯成這樣:

public bool TryGetValue(TKey key, out TItem value) 
{ 
    WeakReference<TItem> weakReference; 

    if (_itemStorage.TryGetValue(key, out weakReference)) 
    { 
     if (weakReference.TryGetTarget(out value)) 
     { 
      return true; 
     } 
     else 
     { 
      value = default(TItem); 
     } 
    } 

    return false; 
} 

在此代碼value變量,如果第一if是假的沒有被設置。

你真正想要的是什麼 - 我想您了 - 是這樣的:

public bool TryGetValue(TKey key, out TItem value) 
{ 
    WeakReference<TItem> weakReference; 

    if (_itemStorage.TryGetValue(key, out weakReference)) 
    { 
     if (weakReference.TryGetTarget(out value)) 
     { 
      return true; 
     } 
    } 
    else 
    { 
     value = default(TItem); 
    } 

    return false; 
} 

這不是指定括號和假設else的列位置是正確的危險。

+0

Hooray,如果最後指出了'明顯'的解析! – user2864740

相關問題