我用來創建接口,使用IEnumerable<T>
作爲返回類型,只要我想指定某個輸出是隻讀的。我喜歡它,因爲它很簡約,隱藏了實現細節並將來自調用者的被調用者分開。IEnumerable <T>的異常處理存在問題,它依賴於惰性
但是最近我的一位同事爭辯說IEnumerable<T>
應該只保留用於懶惰評估的情況,否則對於調用者方法來說不清楚,異常處理應該把它放在位置 - 圍繞方法調用或圍繞迭代。然後,對於只讀輸出的急切評估案例,我應該使用ReadOnlyCollection
。
聽起來對我來說很合理,但你會推薦什麼?你會同意IEnumerable的那個約定嗎?或者有更好的IEnumerable的異常處理方法嗎?
爲防萬一我的問題不清楚,我做了一個樣本類來說明問題。這裏有兩種方法具有完全相同的簽名,但它們需要不同的異常處理:
public class EvilEnumerable
{
IEnumerable<int> Throw()
{
throw new ArgumentException();
}
IEnumerable<int> LazyThrow()
{
foreach (var item in Throw())
{
yield return item;
}
}
public void Run()
{
try
{
Throw();
}
catch (ArgumentException)
{
Console.WriteLine("immediate throw");
}
try
{
LazyThrow();
}
catch (ArgumentException)
{
Console.WriteLine("No exception is thrown.");
}
try
{
foreach (var item in LazyThrow())
{
//do smth
}
}
catch (ArgumentException)
{
Console.WriteLine("lazy throw");
}
}
}
更新1問題是不僅限於ArgumentException的。這是關於製作友好的類接口的最佳實踐,它告訴你他們是否返回延遲評估結果,因爲這會影響異常處理方法。
假設IEnumerable應該保持懶惰評估是無意義的,因爲它從來沒有與懶惰評估掛鉤。在惰性評估是C#中的一個常見範例之前,IEnumerable就已存在。 – Joren 2009-11-15 21:21:17