2012-07-19 23 views
2

考慮下面的例子。設計公共API時我們應該避免IEnumerable作爲輸入嗎?

假設我開發了一個將由第三方使用的庫。該庫有一個方法,接受IEnumerable,這很好,因爲它從傳遞的集合的實現中抽象出來。但是,當我檢索輸入參數時會發生懶惰評估。

public interface IStorage<in T> 
{ 
    void Store(IEnumerable<T> values); 
} 

public class FileStorage<T> : IStorage<T> 
{ 
    public void Store(IEnumerable<T> values) 
    { 
    foreach (var value in values) { /*Evaluation of IEnumerable*/} 
    } 
} 

一些客戶使用我的圖書館以下列方式:

IEnumerable<int> values; 
    try 
    { 
    values = new[] { "1", "2", "three" }.Select(int.Parse); 
    } 
    catch (Exception) 
    { 
    values = Enumerable.Empty<int>(); 
    } 

    var storage = new FileStorage<int>(); 
    storage.Store(values); 

這將導致Store方法,其中評價發生內部異常。如果我設計Store方法採取List<T>我肯定它是安全枚舉集合的Ts。問題是我們應該在設計API時避免IEnumerable,或者我們是否應該在需要時允許並枚舉安全上下文,因爲它可能會引發異常。

回答

1

就我個人而言,我看不出您的方法中引發異常的問題。
這個錯誤,你的API的用戶應該知道它。

+0

好,不過我可能需要做一些清理工作(如關閉數據庫連接),所以我想知道有什麼可以拋出異常 – nan 2012-07-19 18:53:33

+1

@nan:一'using'塊是處理這種情況的標準方法。正確使用它將確保任何異常都會導致您的連接關閉。 – Guvante 2012-07-19 18:56:01

+0

它不僅僅是處理它的事實,我需要恢復一些異常狀態,我需要了解它們。 – nan 2012-07-19 18:58:32

0

是的,在庫中有最抽象的接口作爲參數是一種很好的做法。 您以這種方式定義這些項目的合同。

如果您只需要枚舉集合,那麼IEnumerable是一個非常好的選擇。

如果您希望能夠添加,索引等項目,IList是正確的選擇。

1

事實上,您的客戶端的代碼是越野車不是你的問題。如果他們希望他們的程序能夠工作,請告訴他們停止編寫錯誤代碼。你無法保護他們免受這些查詢被懶惰評估的事實,他們顯然不知道這一點。

這是客戶的責任來處理,當你枚舉集合發生了什麼,以及如果他們通過你懶洋洋地評估收集,那麼它是他們責任確保這種懶惰的評價不能扔(如果這些是你定義的參數)。打破這個不變是他們的問題。

0

作爲一個方面說明,這裏的問題不在於您的API採用IEnumerable。實際的問題是.Select調用。延遲評估是LINQ的一項功能,而不是IEnumerable界面的功能。

所以是的,你應該把一個IEnumerable作爲參數。資源的加載和管理完全由客戶控制,而不是你的。僅僅因爲客戶端可能會傳入IEnumerable的某些實現,這可能會導致延遲報告異常,因此不會犧牲API的可維護性和靈活性。

3

根據Krzysztoc Cwalina和Brad Adams編寫的框架設計指南

http://blogs.msdn.com/b/kcwalina/archive/2008/01/03/frameworkdesignguidelines2ndedition.aspx

它建議你做...

從252頁(8.3.1)的提取

收集參數

DO用最少的專門類型的可能作爲參數的類型。大多數 成員以收藏作爲參數使用了IEnumerable接口

public void PrintNames(IEnumerable<string> names) { 
     foreach(string name in names) { 
      Console.WriteLine(name); 
     } } 

避免使用的ICollection或ICollection的作爲參數只是爲了 訪問Count屬性。

而是考慮了IEnumerable或IEnumerable和動態 檢查對象是否實現的ICollection或ICollection的

順便提一下它的一個偉大的書和一個值得讀,現在真的很享受它。 P.S.誰寫了這傢伙,幫助撰寫了.NET框架

相關問題