2013-11-26 58 views
1

我有以下代碼:收益率回報怪異的行爲

virtual public IEnumerable<string> GetSelectedIds(){ 
    if (_kids == null) 
     yield return null; 
    foreach (var current in _kids.Nodes) 
     yield return current; 
} 

這段代碼在_kids.NodesNullPointerException如果_kids == null

我希望這種方法的前提水平,如果_kids == null返回崩潰但它不!

問題

爲什麼在方法開始時的前提條件有沒有影響?

+2

'yield return'不停止枚舉 - 你應該使用'yeild break'作爲金剛建議的 –

+0

如果'_kids == null'你會考慮返回一個空序列嗎? –

+0

@AhmedKRAIEM是的,那應該很好。 – GETah

回答

5

變化

if (_kids == null) 
     yield return null; 

if (_kids == null) 
     yield break; 

這將返回一個空序列和用戶將不必檢查返回值。

,或者你可以重寫是

public IEnumerable<string> GetSelectedIds(){ 
    if (_kids == null) 
     return null; 

    return GetSelectedIds2(); 
} 

private IEnumerable<string> GetSelectedIds2() 
{ 
    foreach (var current in _kids.Nodes) 
     yield return current; 
} 
+1

不需要 - 如果'_kids'爲'null',OP希望'null'從枚舉器返回 –

+1

@lazyberezovsky OP沒有這樣說,我認爲最好返回一個空序列。 –

+0

+1!感謝您的快速回答,可能是最好的答案,因爲我需要返回一個空的枚舉,而不是:) – GETah

7

試試這個:

virtual public IEnumerable<string> GetSelectedIds(){ 
    if (_kids == null){ 
     yield return null; 
     yield break; 
    } 
    foreach (var current in _kids.Nodes) 
     yield return current; 
} 
+1

+1!感謝你及時的答覆。然而,我倒像'yield return null'是重複的。 – GETah

+0

@GETah是的,這取決於OP。我認爲只是讓它「減產」,「更好。 –

+1

確實。順便說一下,我是OP:D – GETah

1

yield return null幾乎肯定不是你想要的東西 - 它不會停止迭代運行(如你發現),你可能不希望無論如何要返回一個空字符串到集合中。

只需將其替換爲產量突破。這樣你會得到一個空的集合。

或者foreachif(_kids != null),這可能會更清楚。

至於爲何前提不停止執行 - 這是yield return的工作方式 - 想像這樣一個方法:

IEnumerable<String> GetStrings() 
{ 
    yield return "MyFirstString"; 
    yield return "MySecondString"; 
    yield return "MyThirdString"; 
} 

這將返回的三個字符串即它不是一個集合在第一個yield return之後停止。

+0

或者更簡單,只需在'foreach'之前插入'else'即可。 – Raidri

+0

@Raidri - 但是然後'yield break'是多餘的...... –

+0

如果你使用'yield break',你的'if(_kids!= null)'也是多餘的。這一點是我所評論的(在擴展你的答案之前)。 – Raidri