[英]what is the best collection type to return in an API
我一直認為在使用公共API時,返回的數組比列表更好,但現在似乎在列表上有所有這些函數都可以通過LINQ等獲得。
這里是否已更改了返回基元或對象集合的最佳實踐?
例如:
Order[] GetOrders();
List<Order> GetOrders();
IEnumerable<Order> GetOrders();
IQueryable<Order> Get Orders();
你想要這個集合是不可變的嗎? IEnumerable<T>
可變嗎? IList<T>
你需要索引嗎? IList<T>
使用列表或數組,API使用者具有添加,刪除,刪除,清除等功能。
使用IEnumerable<T>
,API使用者獲得一個“包”項,沒有特定的順序,沒有索引,也沒有修改集合的方法。
在某些有限的情況下,您可能希望返回IQueryable<T>
,但它們通常特定於逐個構建查詢。
一般來說,我默認為IEnumerable<T>
。 我可能會使用List<T>
作為支持字段,但只想讓用戶使用Add()
,例如 - 不要刪除,清除或其他任何東西,所以我聲明一個public void Add<T>(T item)
只是將項添加到后備字段列表中。
因為我通常只從屬性/方法返回不可變(不可修改)的對象,所以這個答案假定你想要做同樣的事情。
不要忘記ReadOnlyCollection<T>
,它返回一個仍然可以通過索引訪問的不可變集合。
如果您正在使用IEnumerable<T>
並將您的類型發布到無法控制的荒野中,請注意以下事項:
class MyClass {
private List<int> _list;
public IEnumerable<int> Numbers {
get { return _list; }
}
}
因為用戶可以這樣做並弄亂你班級的內部狀態:
var list = (List<int>)myClass.Numbers;
list.Add(123);
這將違反財產的只讀意圖。 在這種情況下,你的getter應該是這樣的:
public IEnumerable<int> Numbers {
get { return new ReadOnlyCollection<int>(_list); }
}
或者,您可以調用_list.ToReadOnly()
。 我完整地寫出來以顯示類型。
這將阻止任何人修改你的狀態(除非他們使用反射,但除非你構建像許多函數式編程語言中使用的那些不可變集合,否則這很難停止,這是另一個故事)。
如果您要返回只讀集合,則最好將成員聲明為ReadOnlyCollection<T>
,然后某些操作執行得更快(獲取計數,按索引訪問項目,復制到另一個集合)。
就個人而言,我希望看到框架包含並使用如下界面:
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
T this[int index] { get; }
int Count { get; }
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
int IndexOf(T item);
}
你可以在IEnumerable<T>
之上使用擴展方法獲得所有這些函數,但它們並不是那么高效。
我認為最常用的類型是IEnumerable<T>
IEnumerable<T>
返回類型,您可以使用yield
關鍵字,這樣可以延遲枚舉和執行方法。 (例如,常見的抱怨是System.IO.Path.GetFiles()不返回IEnumerable<T>
但返回一個數組,這意味着當您調用該方法時,無論您是否需要它們,都需要枚舉所有項目或沒有。 - 你有與List<T>
相同的劣勢 IEnumerable<T>
IEnumerable<T>
返回類型不會假設有關調用者的任何特定內容。 如果調用者需要列表或數組,他們總是可以創建一個。 IEnumerable<T>
由List<T>
和Array
實現,因此很容易更改方法的實現並仍然支持以前的返回類型。 除了其他人所說的之外,我想補充一點,除非你從一些遠程數據源中檢索對象,否則你永遠不應該返回IQueryable
。 IQueryable
是一個查詢對象 ,它將代表調用者獲取結果。 使用LINQ時, IQueryable
通常會使用一個表達式樹,該表達式樹將被翻譯以供其他系統(例如SQL Server)使用。
有關詳細信息,請參閱http://weblogs.asp.net/fredriknormen/archive/2008/12/01/returning-iqueryable-lt-t-gt.aspx 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.