2011-12-03 54 views
4

就我個人而言,我是C#中IEnumerable/List擴展方法的流暢接口語法的粉絲,作爲客戶端。也就是說,我更喜歡這樣的語法:IEnumerable擴展與無投保證書

public void AddTheseGuysToSomeLocal(IEnumerable<int> values) 
    { 
     values.ToList().ForEach(v => _someLocal += v); 
    } 

而不是像foreach循環那樣的控制結構。我發現,一目瞭然,輕鬆處理思想。與此問題是,如果客戶端傳遞給我一個空參數,這裏我的代碼將生成空引用異常。

讓我們假設我不想考慮一個空枚舉是例外 - 我希望這導致留下一些本地的 - 我會添加一個空警戒。但是,這對我的口味來說有點句法上的嘈雜,如果你將它們連接在一個流暢的界面中,並且中間結果也可以爲空,那麼噪音就會增加。

因此,我創建了一個名爲SafeEnumerableExtensions的類,通過將空值視爲空枚舉(列表)來提供了一個無投訴保證。示例方法包括:

//null.ToList() returns empty list 
    public static List<T> SafeToList<T>(this IEnumerable<T> source) 
    { 
     return (source ?? new List<T>()).ToList(); 
    } 

    //x.SafeForEach(y) is a no-op for null x or null y 
    //This is a shortcut that should probably go in a class called SafeListExtensions later 
    public static void SafeForEach<T>(this List<T> source, Action<T> action) 
    { 
     var myAction = action ?? new Action<T>(t => { }); 
     var mySource = source ?? new List<T>(); 
     mySource.ForEach(myAction); 
    } 

    public static void SafeForEach<T>(this IEnumerable<T> source, Action<T> action) 
    { 
     SafeToList(source).SafeForEach(action);    
    } 

現在,我原來的方法是漂亮比,如果有一個空衛,但只是作爲安全的,因爲空結果在無操作:

public void AddTheseGuysToSomeLocal(IEnumerable<int> values) 
    { 
     values.ForEach(v => _someLocal += v); 
    } 

所以,我的問題是雙重的。 (1)我假設我並非如此原始,以至成爲有史以來第一個想到這一點的人 - 有誰知道是否有現成的圖書館可以做到這一點或類似的東西? (2)有沒有人使用過這樣的圖書館,或者實施了這樣的方案,並且經歷了不愉快的後果,否則任何人都可以預見到做這樣的事情會產生不愉快的後果?這是個好主意嗎?

(我發現this question的重複檢查的時候,但我不希望明確做這種檢查在客戶 - 我想擴展類隱式地做到這一點,而不是用額外的方法調用打擾客戶端)

+0

我打算給你一個非常非常長的序列。你會遍歷整個序列,所以你可以使用一個方法而不是標準循環?然後*然後*您將再次遍歷整個序列以完成實際工作? –

+0

@AnthonyPegram我認爲他只是在談論檢查你通過*的列表引用是否爲null *而不是引用的列表*是否包含空值* – phoog

+1

@phoog,你沒有傳遞一個列表。你正在傳遞一個IEnumerable。他調用了ToList,它遍歷整個序列,簡單地說,他可以使用一種方法,它不僅僅是普通的舊循環,而且(當然)他會再次運行序列(在方法中)。關於空值檢查,我從我的評論中刪除了這部分內容,但不管怎樣,我很清楚他正在談論序列參考。 –

回答

7

(2)有沒有人使用過這樣的庫或者實現了像這樣的方案 ,並且遇到了不愉快的後果,或者任何人都可以預見到 會產生不愉快的後果嗎?這是甚至 好主意?

我個人認爲這是一個壞主意。在大多數情況下,傳遞null枚舉或null Func可能不是意圖。

您正在「修復」可能導致看似無關問題的問題。相反,我寧願在這種情況下拋出異常,以便在代碼早期("Fail fast")中發現此問題。

+0

這是一個很好的觀點。在我發佈的具體示例方法中,將null傳遞給該方法沒有任何意義。但是,我想知道是否有更多微妙的例子,其中快速失敗的概念並不明確。 –

+0

我打算接受這個答案,因爲它似乎是我在考慮這種做法時應該考慮的主要問題 - 我是否幫助客戶掩蓋了問題。感謝您的輸入。 –