2010-04-27 24 views

Trả lời

9

Một IEnumerable không phải là một tập có thứ tự.
Mặc dù hầu hết các IEnumerables được đặt hàng, một số (chẳng hạn như Dictionary hoặc HashSet) thì không.

Do đó, LINQ không có phương thức IndexOf.

Tuy nhiên, bạn có thể viết một mình:

///<summary>Finds the index of the first item matching an expression in an enumerable.</summary> 
///<param name="items">The enumerable to search.</param> 
///<param name="predicate">The expression to test the items against.</param> 
///<returns>The index of the first matching item, or -1 if no items match.</returns> 
public static int FindIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate) { 
    if (items == null) throw new ArgumentNullException("items"); 
    if (predicate == null) throw new ArgumentNullException("predicate"); 

    int retVal = 0; 
    foreach (var item in items) { 
     if (predicate(item)) return retVal; 
     retVal++; 
    } 
    return -1; 
} 
///<summary>Finds the index of the first occurence of an item in an enumerable.</summary> 
///<param name="items">The enumerable to search.</param> 
///<param name="item">The item to find.</param> 
///<returns>The index of the first matching item, or -1 if the item was not found.</returns> 
public static int IndexOf<T>(this IEnumerable<T> items, T item) { return items.FindIndex(i => EqualityComparer<T>.Default.Equals(item, i)); } 
+0

Hmm, nhưng nếu bạn nói nó không phải là một bộ đặt hàng, tôi không nên sử dụng một IList khi tôi muốn cái gì đó nghĩa vụ phải được đặt hàng? Dường như với tôi rằng bằng cách sử dụng IEnumerable để sau đó phải tái thực hiện các bánh xe là kinda vụng về. –

+1

Có, bạn nên sử dụng 'IList '. – SLaks

+8

Nếu thực tế là 'IEnumerable' không phải lúc nào cũng được thúc đẩy khi không có phương thức mở rộng 'IndexOf', thì tại sao chúng ta có' ElementAt'? – Trillian

1

Lưu ý rằng không thể có bất kỳ phương pháp dụ vì IEnumerable là hiệp biến.

Mọi thứ thuộc loại IEnumerable<string> phải triển khai IndexOf(string x) và do hiệp phương sai, có thể được đúc thành IEnumerable<object>.

Vì vậy, hiện tại nó hiển thị là IndexOf(object x) điều thực sự là IndexOf(string x) và vì không phải tất cả objects đều là strings, không thể hoạt động cho tất cả các đối tượng.

IList có thể làm điều đó bởi vì nó bất biến, tức là bạn không thể đúc IList<string> đến IList<object>.

Các vấn đề liên quan