2008-12-02 42 views
6

Trong một câu hỏi khác trên SO, tôi đã trả lời bằng mã như dưới đây và nhận được một nhận xét rằng truy vấn LINQ có lẽ đã được đánh giá trong mỗi lần lặp của/cho mỗi. Điều đó có đúng không?Truy vấn LINQ này có chạy trên mỗi lần lặp của vòng lặp for-each không?

Tôi biết rằng LINQ-truy vấn không thực hiện trước khi các mục của nó được đánh giá vì vậy có vẻ như cách này để lặp lại kết quả có thể làm cho nó chạy trên mỗi lần lặp?

Dim d = New Dictionary(Of String, String)()  
d.Add("Teststring", "Hello")  
d.Add("1TestString1", "World")  
d.Add("2TestString2", "Test")  

For Each i As String In From e In d Where e.Value.StartsWith("W") Select e.Key 
    MsgBox("This key has a matching value:" & i)  
Next 
+0

Cũng giống như những gì bạn có là OK, nhưng ít nhất là định dạng với dòng cuối _ vì vậy nó không phải trên một dòng lớn :) –

+0

Vâng. Điều này đánh giá cuối với LINQ sẽ mất một thời gian để làm quen với. – Stefan

+0

Vâng, nhưng nó rất tuyệt khi bạn có được nó, bạn có thể làm một số thứ khá ngọt ngào. –

Trả lời

7

KHÔNG ... trong một foreach, "GetEnumerator" được gọi chỉ một lần (bao giờ) và được sử dụng trong tương lai.

EDIT: Tôi đặt một tuyên bố ở đây về tập kết quả được lưu trữ tạm thời ... điều đó chỉ đúng đối với một số trường hợp ... không phải cái này, vì vậy tôi lấy nó ra.

EDIT: Xin hãy tha thứ này vì đã quá dài dòng ... nhưng tôi muốn chương bạn biết những gì đang xảy ra ... vì vậy đây là một ứng dụng Console :)

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      foreach (string item in MyCustomEnumerator() 
       .Where(item => item.StartsWith("abc"))) 
      { 
      Console.WriteLine(item); 
      } 
     } 

     static IEnumerable<string> MyCustomEnumerator() 
     { 
      Console.WriteLine(DateTime.Now); 

      yield return "abc1"; 

      Console.WriteLine(DateTime.Now); 

      yield return "abc2"; 

      Console.WriteLine(DateTime.Now); 

      yield return "abc3"; 

      Console.WriteLine(DateTime.Now); 

      yield return "xxx"; 
     } 
    } 
} 

EDIT: Điều này sẽ dẫn đến một DateTime, sau đó abc1, sau đó một DateTime, sau đó abc2, sau đó một DateTime, sau đó abc3, sau đó một DateTime.

+2

Cảm ơn. Và pheuw. Tôi đã sử dụng cách đó để lặp qua các kết quả LINQ rất nhiều trong một dự án gần đây. ;) – Stefan

0

Tôi đã tra cứu câu lệnh FOR ...

Số lần lặp lại. Visual Basic chỉ đánh giá bộ sưu tập một lần, trước khi bắt đầu vòng lặp. Nếu phần tử thay đổi khối tuyên bố hoặc của bạn, những thay đổi này không ảnh hưởng đến việc lặp lại vòng lặp .

1

Tôi tin rằng nó sẽ chạy lần đầu tiên nó được tiếp cận và tạo ra một liệt kê có tất cả các giá trị phù hợp. Những gì bạn thực sự sẽ quay trở lại là một điều tra viên cho điều tra đó.

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