2010-01-22 4 views
14

C# 2 và VB.Net 8 đã giới thiệu một tính năng mới có tên là iterators, được thiết kế để làm cho việc trả lại số đếm và liệt kê dễ dàng hơn.Sử dụng thông minh của .Net 2 Iterators

Tuy nhiên, trình vòng lặp thực sự là một dạng giới hạn là coroutines và có thể được sử dụng để thực hiện nhiều việc hữu ích không liên quan gì đến bộ sưu tập đối tượng.

Sử dụng các trình vòng lặp không chuẩn nào bạn đã thấy trong mã thực?

+0

Tại sao hạn chế nó đến C#? – ChaosPandion

+0

@Chaos: Tôi không nhận ra rằng họ cũng được hỗ trợ bởi VB. Đã chỉnh sửa. – SLaks

+1

Thực ra, các khối lặp không phải là tính năng ".NET" (có nghĩa là: thời gian chạy). Chúng là các tính năng ngôn ngữ, được cung cấp hoàn toàn bởi trình biên dịch. –

Trả lời

11

Tôi đã sử dụng chúng để viết hệ thống trong ASP.NET để tạo chuỗi tương tác trang được liên kết. Nếu bạn tưởng tượng cuộc trò chuyện của người dùng với trang web dưới dạng một loạt các yêu cầu và phản hồi, bạn có thể lập mô hình tương tác dưới dạng IEnumerable. Về mặt khái niệm, như thế này;

IEnumerable<PageResponse> SignupProcess(FormValues form) 
{ 
    // signup starts with a welcome page, asking 
    // the user to accept the license. 
    yield return new WelcomePageResponse(); 

    // if they don't accept the terms, direct 
    // them to a 'thanks anyway' screen 
    if (!form["userAcceptsTerms"]) 
    { 
     yield return new ThanksForYourTimePageResponse(); 
     yield break; 
    } 

    // On the second page, we gather their email; 
    yield new EmailCapturePage(""); 
    while(!IsValid(form["address"])) 
    { 
    // loop until we get a valid address. 
    yield return new EmailCapturePage("The email address is incorrect. Please fix."); 
    } 
} 

Bạn có thể lưu trữ các iterator trong trạng thái phiên, để khi trở về dùng đến trang web của bạn chỉ cần kéo các iterator ra, di chuyển iterator vào trang tiếp theo, và mang nó trở lại để render. Tương tác trang web phức tạp được mã hóa ở một nơi duy nhất.

+0

(Tôi đã cố định cú pháp 'yield' của bạn) Tôi thực sự thích ý tưởng đó. Nó sẽ tốt hơn với ASP.Net MVC, nhưng nó có thể mất một số thủ thuật để thiết lập. – SLaks

+0

Cảm ơn. Tôi nghi ngờ bạn có thể tách ra các công cụ định tuyến tiêu chuẩn từ MVC, nhưng tôi nghĩ rằng bạn đang đúng - nó muốn được rất nhiều công việc. Tôi cũng có _no idea_ làm thế nào tôi sẽ làm cho nó làm việc với các cuộc gọi async async ... –

+0

Bạn sẽ đặt ở đâu giữa các yêu cầu trang?Trên máy chủ được nhóm không quốc tịch? Tôi không chắc điều đó thật tuyệt vời, xin lỗi. –

8

Để bắt đầu điều off:

  • Jeffrey Richter đã viết một hệ thống luồng mạnh mẽ gọi là AsyncEnumerator sử dụng vòng lặp. Nó được mô tả trong Tạp chí MSDN, các bộ phận onetwo.
  • Các bộ lặp cũng có thể được sử dụng để đợi tương tác giao diện người dùng trong một phương thức mà không chặn luồng giao diện người dùng, như tôi đã mô tả here.
  • Trong một mạch tương tự, tôi đã sử dụng trình vòng lặp để tạo một trình duyệt web dựa trên IE, với phương thức cạo trả lại các trình đếm số của WebAction mà gọi lại vào điều tra khi sẵn sàng. (Thông thường, khi tài liệu kết thúc tải).
    Nếu mọi người quan tâm, tôi có thể đăng bài ở đây.
0

Tôi đã viết chức năng này trước khi tôi phát hiện ra về toán tử lợi nhuận lười biếng. Điều này đệ quy xây dựng một iterator lớn và trả về nó. Nó không chính xác hiệu quả nhưng tôi nghĩ nó rất thông minh.

static member generatePrimeNumbers max =  
    let rec generate number numberSequence = 
     if number * number > max then numberSequence else 
     let filteredNumbers = numberSequence |> Seq.filter (fun v -> v = number || v % number <> 0L) 
     let newNumberSequence = seq { for i in filteredNumbers -> i } 
     let newNumber = newNumberSequence |> Seq.find (fun x -> x > number) 
     generate newNumber newNumberSequence     
    generate 2L (seq { for i in 2L..max -> i }) 
+0

Ngôn ngữ đó là gì? F #? – SLaks

+0

Vâng, từ khóa seq là một bí danh cho IEnumerable. – ChaosPandion

1

Tôi đã sử dụng nó để đệ quy lặp qua các tệp có trong thư mục, thư mục con của nó và cứ tiếp tục như vậy. Đối với mỗi tập tin tôi đã phải thực hiện một hành động cụ thể. Một hàm đệ quy với các câu lệnh "return return" rất đơn giản cho sự hiểu biết của người khác.

0

Rhino.ETL tận dụng nặng nề của nó để kết hợp biến đổi qua một chuỗi các đầu vào

ví dụ 3 hoạt động có thể được kết hợp, tái sử dụng

public IEnumerable<Row> Execute(IEnumerable<Row> rows) 
{ 
    foreach(var line in File.EnumerateLines()) 
    { 
     var row = new Row(); 
     row["key"] = int.Parse(line.Substring(1)); 
     yield return row; 
    } 
} 

public IEnumerable<Row> Execute(IEnumerable<Row> rows) 
{ 
    foreach(var row in rows) 
    { 
     var value = (int)row["key"]; 
     row["key"] = value + 2; 
     yield return row; 
    } 
} 

public IEnumerable<Row> Execute(IEnumerable<Row> rows) 
{ 
    using (var file = new Streamwriter(filename)) 
    { 
     foreach(var row in rows) 
     { 
      file.WriteLine(row["key"]); 
      yield return row; 
     } 
    } 
}