2011-10-01 75 views
1

請假設我有以下的擴展方法,以便能夠強制IEnumerable的評價:接口向下轉換

public static List<T> EvaluateNow<T>(this IEnumerable<T> collection) 
{ 
    if (collection == null) 
    { 
     throw new ArgumentNullException("collection"); 
    } 
    else 
    { 
     return (collection.ToList()); 
    } 
} 

我想問一下,如果有在具有IList<T>而不是List<T>因爲這樣的任意點方法的返回類型(即向下轉換爲接口),以便既不將它也不依賴於特定的實現(即使返回值實際上總是爲List)。

+4

對於這個特定的功能,我不這麼認爲。另外我不認爲它的值得擁有這樣的擴展方法,它只是運行'.ToList()' – Magnus

+1

IList 允許許多實現之一,其中一個是列表。如果這對支持未來結構變化並不重要,那麼不會。 – kenny

+0

但是,這是一個很好的習慣。 –

回答

3

它是總是在這種情況下使用接口而不是類是一個好主意。
爲什麼會有太多的原因不能進入這裏,但是例如,它極大地增加了靈活性,因爲任何類只需要實現接口IList<T>即可分配給該函數的返回值。類將實現這個(或其他)接口而無需繼承List(或等價物)。
一般而言,您希望使用符合要求的「最低」等值界面。在這種情況下,你可以考慮ICollection,或者甚至IEnumerable而不是IList。

這是無關緊要的,你從函數返回什麼類的實例,因爲只有「接口」返回,因此它可以被分配到實現該接口的任何類(再次,最大的flexibilty?)

通常是功能返回一些IEnumerable對象將主要在foreach循環中使用。

+1

微軟顯然認爲'ToList()'應該返回'List '而不是'IList ' – Magnus

1

擴展方法只能在實例上調用。這意味着您的方法中collection永遠不會是null

因此......正如您所寫的,您的方法具有與擴展方法IEnumerable.ToList完全相同的行爲,所以我沒有看到任何一點。

如果其返回類型爲IList,如Aaron在his answer中所解釋的那樣,這將是有用的。

爲什麼IEnumerable.ToList尚未返回IList對於圖書館設計人員來說是個好問題。

+0

你有沒有嘗試過'IList newList =空值; int newInt = newList.First();'?當你應用擴展方法'First()'(在'System.Linq'上定義)時,編譯器不會抱怨,但是當你運行程序時你肯定會得到一個異常,所以我會說擴展方法確實可以調用'null'引用。 – DotNetStudent

+1

@DotNetStudent的確我站得更正了。但行爲仍然是一樣的。拋出'ArgumentNullException'。我會修改我的答案。 –

+1

但是'ToList()'在內部拋出與你的方法相同的異常,這意味着就像@Hemal說你剛剛爲ToList()創建了一個別名 – Magnus