簡體   English   中英

如何在IList或IEnumerable之間選擇方法參數類型

[英]How to choose between IList or IEnumerable as method parameter type

我正在編寫一個庫,並試圖確定用於方法參數的最佳類型。 我還試圖確定在過於挑剔和獲取write方法定義之間的界限。

這是一些代碼

public void MethodTakesIList(IList<MyClass> myClassInstances) {
  List<List<byte>> byteLists = GetByteLists(myClassInstances.Count);
  for (int i = 0; i < myClassInstances.Count; i++) {
    ProcessBytesAndMyClassInstance(byteLists[i], myClassInstances[i]);
  }
} 

public void MethodTakesIEnumerable(IEnumerable<MyClass> myClassInstances) {
  List<List<byte>> byteLists = GetByteLists(myClassInstances.Count());
  int i = 0;
  foreach(MyClass instance in myClassInstances) {
    ProcessBytesAndMyClassInstance(byteLists[i], instance);
    i++;
  }
}

這個文章它說我“應該總是使用類型為只有你真正使用的方法的合同。” 采用IEnumerable的方法仍定義循環中使用的索引。 因為如果myClassInstances是一個列表 ,此索引將指向一個有效的條目,這是否意味着我應該只使用接受IList的方法? 我現在可以使用IList的索引器。 還是由於存在一種接受IEnumerable的解決方案,因為它支持最大數量的輸入,因此我應該使用該解決方案嗎?

如果您是我,我將從Microsoft如何實現LINQ中獲得啟發。 許多可以從使用集合類型中受益的運算符仍然將IEnumerable<TSource>作為源數據,但是他們只是嘗試將其ICollection<TSource>轉換為ICollection<TSource>以直接訪問索引和其他屬性。

Count (對此稍作修改)為例:

public static int Count<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }
    ICollection<TSource> collection = source as ICollection<TSource>;
    if (collection != null)
    {
        return collection.Count;
    }
    ICollection collection2 = source as ICollection;
    if (collection2 != null)
    {
        return collection2.Count;
    }
    int num = 0;
    using (IEnumerator<TSource> enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            num = checked(num + 1);
        }
        return num;
    }
}

如果輸入類型可轉換為集合,則Count運算符只返回計數; 否則,將遍歷列表。

這樣一來,您就可以充分利用這兩種類型。

如果不確定人們將如何使用API​​, IEnumerable通常是一個安全的選擇。 在很多情況下,除了列表以外的其他任何集合(例如LinkedListQueue之外,用戶都將沒有IList對象,尤其是使用Linq中的東西時。

例如,如果他們執行someList.Select((x) => new OtherThing(x, "test")) ,使用Where等進行過濾,那么它們將以IEnumerable結尾。 盡管System.Linq還有一個方便的myEnumerable.ToList()但它們是他們必須進行的一次額外轉換,並且會對性能產生影響,可能比您希望避免的轉換更糟糕。

當然,有時出於性能原因,最好使用其他類型,尤其是在處理大量小值(例如byte[] )或簡化實現(例如用於隨機訪問或修改數據)時。

您可能需要自己權衡取舍,盡管您可能會從該語言的標准類和其他流行的庫中獲得啟發。 對於公共庫,在考慮二進制兼容性時也必須非常小心,例如,如果返回IEnumerable則可以將實現更改為使用不同的實際類型,如果返回ListIList則在限制什么方面更受限制。在不破壞兼容性的情況下在技術上是可行的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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