Làm thế nào để lặp qua một bộ sưu tập hỗ trợ IEnumerable?


Câu trả lời:


155

Một thường xuyên cho mỗi sẽ làm:

foreach (var item in collection)
{
    // do your stuff   
}

Điều này nhanh hơn .ElementAt (). Rất tiếc, phiếu bầu của tôi bị khóa đối với câu trả lời của Alexa nên tôi không thể hoàn tác nhưng đây là câu trả lời hay nhất. +1
Leo Gurdian

Vậy làm thế nào để bạn sửa lỗi "Có thể liệt kê nhiều IEnumerable"?
SharpC

1
@SharpC: cách dễ nhất là kéo kết quả vào Danh sách <T> hoặc một mảng, sau đó chuyển kết quả đó đến những nơi khác nhau cần lặp lại. Điều này đảm bảo rằng việc liệt kê (có thể tốn kém) kết quả chỉ xảy ra một lần, nhưng với chi phí lưu trữ kết quả trong bộ nhớ. Bước đầu tiên của tôi là tìm hiểu xem liệu phép liệt kê có thực sự là một vấn đề hay không.
Fredrik Mörk

94

Cùng với các phương pháp sử dụng foreachvòng lặp đã được đề xuất , tôi nghĩ rằng tôi cũng muốn đề cập rằng bất kỳ đối tượng nào triển khai IEnumerablecũng cung cấp một IEnumeratorgiao diện thông qua GetEnumeratorphương thức. Mặc dù phương pháp này thường không cần thiết, nhưng phương pháp này có thể được sử dụng để lặp lại thủ công qua các tập hợp và đặc biệt hữu ích khi viết các phương thức mở rộng của riêng bạn cho các tập hợp.

IEnumerable<T> mySequence;
using (var sequenceEnum = mySequence.GetEnumerator())
{
    while (sequenceEnum.MoveNext())
    {
        // Do something with sequenceEnum.Current.
    }
}

Một ví dụ chính là khi bạn muốn lặp lại đồng thời hai chuỗi , điều này không thể thực hiện được với một foreachvòng lặp.


7
Đừng quên loại bỏ điều tra viên.
Eric Lippert

@Eric: Đúng vậy, tôi sẽ thêm nó vào vì nó rất dễ bỏ sót.
Noldorin

1
Tôi nghĩ rằng điều đó sẽ chỉ hoạt động cho các đối tượng IEnumerable <T> và không cho IEnumerable. Tôi có một trường hợp chung mà tôi phải truyền sang IEnumerable và do đó, tôi không có sẵn phương thức GetEnumerator. Tốt cho hầu hết các trường hợp dù sao.
Fabio Milheiro

50

hoặc thậm chí là một phương pháp cổ điển rất cổ điển

IEnumerable<string> collection = new List<string>() { "a", "b", "c" };

for(int i = 0; i < collection.Count(); i++) 
{
    string str1 = collection.ElementAt(i);
    // do your stuff   
}

có thể bạn cũng muốn phương pháp này :-)


9
Tại sao điều này có rất nhiều ủng hộ? Thao tác này sẽ liệt kê 2n lần thay vì một lần.
Roman Reiner

1
@RomanReiner vì công trình này, một số người không bận tâm về hiệu suất :)
Khateeb321

@RomanReiner đây là một ví dụ điển hình, tôi cần gán từng phần tử của một Bộ sưu tập cho một bộ sưu tập khác, tôi nghĩ rằng tôi không thể làm điều này bằng foreach
AminM

1
Nếu bạn nhìn vào việc triển khai ElementAt, bạn sẽ thấy rằng nếu tập hợp là IList, chúng sẽ trả về phần tử tại chỉ mục bằng cách sử dụng []; Tuy nhiên, hiệu suất tương tự như []; nếu không, họ sẽ nhận được Enumerator và bắt đầu một lần lặp tuần tự tìm kiếm nguyên tố này trước khi trở về nó, vì vậy về cơ bản cho mỗi phần tử họ tạo ra một Enumerator mới và điều hướng danh sách một lần nữa ...
Israel Garcia

1
Còn tệ hơn tất cả, IEnumerable không hỗ trợ Count () hoặc ElementAt (). Tôi nghĩ anh ấy đang nghĩ đến một IList. Điều này thực sự không trả lời câu hỏi nào cả.
krowe


0

Có thể bạn đã quên việc chờ đợi trước khi trả lại bộ sưu tập của mình

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.