Lưu ý: câu trả lời này áp dụng cho Java nhiều hơn là cho C #, vì C # không bật trình lập chỉ mục LinkedLists, nhưng tôi nghĩ rằng điểm chung vẫn được giữ nguyên.
Nếu listbạn đang làm việc là a LinkedList, thì hiệu suất của mã lập chỉ mục ( truy cập kiểu mảng ) kém hơn rất nhiều so với việc sử dụng IEnumeratorfrom foreach, cho các danh sách lớn.
Khi bạn truy cập phần tử 10.000 trong một LinkedListbằng cú pháp của trình lập chỉ mục:, list[10000]danh sách được liên kết sẽ bắt đầu ở nút đầu và lướt qua Next-pointer mười nghìn lần, cho đến khi nó đến đúng đối tượng. Rõ ràng, nếu bạn làm điều này trong một vòng lặp, bạn sẽ nhận được:
list[0]; // head
list[1]; // head.Next
list[2]; // head.Next.Next
// etc.
Khi bạn gọi GetEnumerator(mặc nhiên sử dụng forach-syntax), bạn sẽ nhận được một IEnumeratorđối tượng có một con trỏ đến nút đầu. Mỗi lần bạn gọi MoveNext, con trỏ đó được di chuyển đến nút tiếp theo, như sau:
IEnumerator em = list.GetEnumerator(); // Current points at head
em.MoveNext(); // Update Current to .Next
em.MoveNext(); // Update Current to .Next
em.MoveNext(); // Update Current to .Next
// etc.
Như bạn có thể thấy, trong trường hợp của LinkedLists, phương thức chỉ mục mảng càng ngày càng chậm, bạn lặp lại càng lâu (nó phải đi qua cùng một con trỏ đầu nhiều lần). Trong khi IEnumerablechỉ hoạt động trong thời gian không đổi.
Tất nhiên, như Jon đã nói, điều này thực sự phụ thuộc vào loại list, nếu listkhông phải là a LinkedList, mà là một mảng, thì hành vi hoàn toàn khác nhau.