Nó không khả dụng vì IEnumerable là trình chuyển tiếp chỉ chuyển tiếp. Nó chỉ có một phương thức MoveNext(). Điều đó làm cho giao diện rất phổ biến và cốt lõi của LINQ. Có rất nhiều bộ sưu tập thế giới thực không thể lặp lại vì yêu cầu phải có bộ nhớ. Hầu hết các luồng đều giống như vậy.
LINQ cung cấp giải pháp với phương thức mở rộng Reverse(). Nó hoạt động bằng cách lưu trữ các phần tử đầu tiên, sau đó lặp lại chúng. Tuy nhiên điều đó có thể rất lãng phí, nó yêu cầu lưu trữ O (n). Nó thiếu một tối ưu hóa có thể cho các bộ sưu tập đã được lập chỉ mục. Mà bạn có thể khắc phục: sử dụng
static class Extensions {
public static IEnumerable<T> ReverseEx<T>(this IEnumerable<T> coll) {
var quick = coll as IList<T>;
if (quick == null) {
foreach (T item in coll.Reverse()) yield return item;
}
else {
for (int ix = quick.Count - 1; ix >= 0; --ix) {
yield return quick[ix];
}
}
}
}
mẫu:
var list = new List<int> { 0, 1, 2, 3 };
foreach (var item in list.ReverseEx()) {
Console.WriteLine(item);
}
Bạn sẽ muốn thực hiện một chuyên môn hóa cho LinkedList vì nó không thực hiện IList <> nhưng vẫn cho phép nhanh chóng lùi lặp thông qua cuối và LinkedListNode.Previous properties. Mặc dù tốt hơn hết là không sử dụng lớp đó, nhưng nó có bộ nhớ cache cục bộ CPU tệ hại. Luôn ưu tiên Danh sách <> khi bạn không cần chèn giá rẻ.Nó có thể trông như thế này:
public static IEnumerable<T> ReverseEx<T>(this LinkedList<T> list) {
var node = list.Last;
while (node != null) {
yield return node.Value;
node = node.Previous;
}
}
Nguồn
2012-02-18 13:59:43
Câu hỏi thú vị, 'MoveNext()' sẽ kinda dường như một nghịch lý đối với một Enumerator ngược mặc dù tôi đoán cho tương thích với 'foreach' 'cái GetReverseEnumerator()' phương pháp sẽ thực sự vẫn phải trả về một 'IEnumerator' và do đó sẽ yêu cầu phương thức đó ngay cả khi' MovePrevious() 'có vẻ phù hợp hơn với tâm trí của tôi – RobV
Có phương pháp mở rộng Reverse linq đạt được một cái gì đó tương tự ... – RQDQ
Trên các kiểu thực hiện' IList ' một 'Reverse' hiệu quả từ linq. Thật không may, không phải mọi kiểu có thể thực thi 'Reverse' một cách hiệu quả, cũng có thể thực thi' IList '. Ví dụ: danh sách được liên kết kép. Vì vậy, tôi đồng ý, rằng những bộ sưu tập có xây dựng trong phương pháp 'Reverse()', sẽ được tốt đẹp. –
CodesInChaos