2017-01-08 24 views
2

通常,提供接受數組的方法可以被優化以接受更通用的類別,這些類別都是IEnumerable並且需要CountLength提供哪種參數類型是IEnumerable並具有Count?

實施例:

public static T NextObject<T>(this Random random, T[] array) 
{ 
    return array[random.Next(array.Length)]; 
} 

在這裏,我使用Array獲取特定的元件,知道元素的量。以一般方式,哪類最適合?

  • 的IList
  • ICollection的 - 也有Count
  • 其他接口或類或一組不同的接口?

認爲IEnumerable可能不是一個好主意,因爲Count()可以對性能產生副作用,如果底層枚舉更爲複雜。

+0

我會建議使用'ICollection ',但我認爲這有點基於*意見*。 – MarcinJuraszek

+0

'ICollection '沒有索引器。我認爲這個和'Array'作爲兩個重載可以*(不確定)*覆蓋所有類型。我不認爲這是基於意見的,因爲這個問題基本上覆蓋了所有常見類型,並且重載最少。 – bytecode77

+0

爲什麼不簡單列表? –

回答

2

您需要通過索引和集合中項目的數量來訪問項目。你也想在收集/接口

     | IList<T> | ICollection<T> | IEnumerable<T> | T[] 
Access by index  |  + |  -  |  -  | + 
Count of items  |  + |  +  |  -  | + 
Less unwanted members |  - |  +  |  +  | ~ 

少其他成員如你所見,ICollection的和IEnumerable不適合您的需求。我沒有看到選擇IList或陣列之間的巨大差異。 IList可能比數組更輕量級,但它有很多不需要的操作(添加,刪除,清除),並且可以使用params,這通常很方便。

+0

非常好的可視化!所以可能提供數組和IList的重載將是最好的......但是如果代碼比示例中更復雜呢?只提供數組並在耗費方法中需要'.ToArray'? – bytecode77

+0

@bytecode77可能是兩個重載,'IList '和'params T []'是最方便的選擇:'ranomd.NextObject(apple,banana,peach)'看起來不錯 –

0

您的方法應該採用滿足方法需求的最不具體的類型。旨在儘可能減少耦合。下面是ICollection

public interface ICollection<T> : IEnumerable<T>, IEnumerable 

簽名因爲無論ICollection<T>也不IEnumerable<T>支持索引,那麼沒有人會工作。

陣列過於具體,但List<T>IList<T>將滿足您的需求,因爲您需要按索引訪問。否則,客戶端(類的使用者)將需要轉換爲數組類型。

但是計數可引起性能的副作用

Count()System.Linq.Enumerable擴展方法。它將嘗試轉換爲支持O(1)計數的類型,如ICollection(Count屬性)。如果沒有可用的,那麼它將遍歷所有項目並計數它們變成O(N)。

+0

如果我沒有弄錯,它甚至是* all *集合類實現'IEnumerable '。但由於它不支持隨機訪問,並且使用'.Skip'具有不確定的性能,所以IEnumerable不能使用。 – bytecode77

+0

@bytecode77對不起,你的問題是關於計數和長度,但我現在看到你的代碼需要隨機索引。編輯答案。 – CodingYoshi

相關問題