簡體   English   中英

什么是API中返回的最佳集合類型

[英]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>相同的劣勢
  • 大多數LINQ擴展方法都適用於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM