2015-10-27 13 views
4

如果我例如有這樣的方法:Enumerable.Empty列出

IEnumerable<int> GetRandomNumbers() 
{ 
    // {Codes that generate numbers as List<int>} 
    if(generationFails == true) 
    { 
     return Enumberable.Empty<int>(); // I do this to signal that we have an error 
    } 
    return numbers; 
} 

在調用方法我做的:

IEnumerable<int> AddNumber(int number) 
{ 
    var random = GetRandomNumbers(); 
    var randomList = random as IList<int> ?? random.ToList(); // Run ToList only if needed 
    randomList.Add(number); 
    return randomList; 
} 

,當生成失敗我得到一個異常「[NotSupportedException異常:收藏是一個固定的大小。]「。

這是因爲Enumerable爲IList,所以.ToList()沒有運行,然後我試圖添加到一個固定的Enumberable.Empty中。我錯誤地認爲這是不好的設計,繼承IList的對象(其中添加了定義)應該支持添加?

我被迫做var randomList = random.ToList()或停止使用Enumberable.Empty?有更好的方法嗎?

更新: 我想我在我的例子中不清楚。我希望吞下(或記錄)錯誤,但允許操作繼續而不會崩潰。我的評論「我這樣做是爲了表明我們有錯誤」是爲了告訴其他開發人員閱讀代碼,這是一種不正常的行爲。

對蒂姆聯繫的問題answer是我所瞭解的。似乎我們只是沒有固定集合的接口,所以使用IList

+2

你爲什麼不簡單地引發異常? 'Enumerable.Empty'是發信號錯誤的最糟糕的方式。 – Sven

+0

你可以隨時讓GetRandomNumbers返回一個布爾值,並輸出列表,然後你可以檢查GetRandomNumbers是否被成功賦值 – JsonStatham

回答

2

其實Enumerable.Emptyreturns an empty array,這就是爲什麼你在Array.IList.Add得到NotSupportedException。數組的大小是固定的。

Why array implements IList?

,如果你想「信號,有一個錯誤」我將返回null,而不是一個空的序列。在可讀性方面,對您的業務邏輯進行類型檢查並不合適。

if(generationFails == true) 
{ 
    return null; // I do this to signal that we have an error 
} 

然後,它很簡單:

IEnumerable<int> random = GetRandomNumbers(); 
IList<int> randomList = random == null ? new List<int>() : random.ToList(); 

空序列表明,一切都很好。考慮將來你會改變這個方法來取一個整數size。現在有人提供0作爲大小,它也返回一個空序列。你不能區分錯誤和空序列。

當然你也可以返回new List<int>而不是Enumerable.Empty<int>

5

更好的方法是返回null或拋出異常。返回一個空列表可以被認爲是一個有效的選擇,但不是在你的方法的上下文中(例如,過濾沒有有效項目的另一個列表)。

失敗的隨機數生成似乎表明生成算法的問題,應拋出一個異常,而不是一個空列表。

Should a retrieval method return 'null' or throw an exception when it can't produce the return value?

如果你總是希望找到一個值,則拋出異常,如果缺少它。這個例外意味着有問題。

如果該值可能丟失或存在,並且兩者都對應用程序邏輯有效,則返回null。

+0

@Martin,如果這個答案對你有幫助,如果你接受它,我會很感激。 – Sven

2

另一種可能的方式來處理,這將是恢復使用yield break一個空的枚舉:

IEnumerable<int> GetRandomNumbers() 
{ 
    if (generationFails) 
     yield break; 

    foreach (var element in numbers) 
    { 
     yield return element; 
    } 
} 

這會讓你的IEnumerable<int>懶洋洋地返回各自的隨機數。

請注意,這不會單擊錯誤到調用代碼。如果generationFails應該在代碼執行中單獨出現錯誤,則應該像其他人所說的那樣,拋出異常。