2013-08-12 35 views
5

Câu hỏi: Kết quả của truy vấn LINQ có luôn được đảm bảo theo đúng thứ tự không?Kết quả của truy vấn LINQ luôn được đảm bảo theo đúng thứ tự?

Ví dụ:

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 

var lowNums = 
    from n in numbers 
    where n < 5 
    select n; 

Bây giờ, khi chúng tôi đi bộ qua các mục của kết quả truy vấn, nó sẽ được theo thứ tự giống như các dữ liệu đầu vào numbers được lệnh?

foreach (var x in lowNums) 
    { 
    Console.WriteLine(x); 
    } 

Nếu ai đó có thể cung cấp ghi chú về thứ tự trong tài liệu, điều này sẽ là hoàn hảo.

+0

Sử dụng 'var lowNums = numbers.Where (x => x <5).OrderBy (x => x); ' –

+1

Có thể điều này sẽ giúp: http://stackoverflow.com/questions/6146724/do-linqs-enumerable-methods-maintain-relative-order-of-elements. Nếu đó là một IEnumerable, nó sẽ mantain thứ tự ban đầu. – thepirat000

Trả lời

4
+0

Bạn có tìm thấy bất kỳ tài liệu nào đảm bảo rằng thứ tự giữ nguyên cho Linq-To-Objects không? –

+0

@TimSchmelter Tôi khá chắc chắn các tài liệu nói ngược lại, hay đúng hơn là, không nói gì cả. – evanmcdonnal

+0

@evanmcdonnal: Tôi khá chắc chắn rằng các tài liệu không nói gì cả ngay cả khi tôi chắc chắn rằng nó không thay đổi thứ tự trong 'Chọn' hoặc các phương thức LINQ khác. –

0

Tôi nghĩ rằng thứ tự của các yếu tố lấy ra bằng một LINQ được bảo tồn, ít nhất là cho LINQ to Object, cho LINQ to SQL or Entity, nó có thể phụ thuộc vào thứ tự của các bản ghi trong bảng. Đối với LINQ to Object, tôi sẽ cố gắng giải thích lý do tại sao nó giữ nguyên thứ tự.

Trong thực tế khi truy vấn LINQ được thực thi, nguồn IEnumerable sẽ gọi điện để GetEnumerator() để bắt đầu vòng lặp với một while loop và nhận được phần tử tiếp theo sử dụng MoveNext(). Đây là cách foreach hoạt động trên nguồn IEnumerable. Chúng ta đều biết rằng foreach sẽ giữ nguyên thứ tự của các thành phần trong danh sách/bộ sưu tập. Đào sâu hơn vào MoveNext(), tôi nghĩ nó chỉ có một số Position để lưu IndexMoveNext() hiện tại chỉ tăng Positionyield thành phần tương ứng (ở vị trí mới). Đó là lý do tại sao cần giữ nguyên thứ tự, tất cả các mã thay đổi thứ tự ban đầu là dư thừa hoặc bằng cách gọi một cách rõ ràng đến OrderBy hoặc OrderByDescending.

Nếu bạn nghĩ rằng đây

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 
foreach(var i in numbers) 
    if(i < 5) Console.Write(i + " "); 

in ra 4 1 3 2 0 bạn nên nghĩ rằng đây

int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; 
IEnumerator ie = numbers.GetEnumerator(); 
while(ie.MoveNext()){ 
    if((int)ie.Current < 5) Console.Write(ie.Current + " "); 
} 

cũng in ra 4 1 3 2 0. Do đó, truy vấn LINQ

var lowNums = from n in numbers 
       where n < 5 
       select n; 
foreach (var i in lowNums) { 
    Console.Write(i + " "); 
} 

cũng sẽ in ra 4 1 3 2 0.

Kết luận: Trình tự của các yếu tố trong LINQ phụ thuộc vào cách MoveNext() của một IEnumerator thu được từ một IEnumerable được thực hiện. Tuy nhiên, chắc chắn rằng thứ tự các phần tử trong kết quả LINQ sẽ giống với một vòng lặp foreach hoạt động trên các phần tử.

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