2008-10-22 28 views
48

Tôi chỉ viết một số mã nhanh chóng và nhận thấy lỗi biên dịch nàyTại sao nó xấu để sử dụng một biến lặp trong một biểu thức lambda

Sử dụng biến lặp trong một biểu thức lambda có thể có kết quả bất ngờ.
Thay vào đó, hãy tạo biến cục bộ trong vòng lặp và chỉ định giá trị của biến lặp.

Tôi biết điều đó có nghĩa là gì và tôi có thể dễ dàng khắc phục nó, không phải là vấn đề lớn.
Nhưng tôi đã tự hỏi tại sao nó là một ý tưởng tồi để sử dụng một biến lặp trong một lambda?
Tôi có thể gây ra vấn đề gì sau này?

+0

liên quan: http://stackoverflow.com/questions/190227/building-a-linq-query-programatically-without-local-variables-tricking-me – nawfal

+0

tốt hơn nếu bạn đưa ra ví dụ thực sự hoạt động/cung cấp kết quả đúng! ví dụ như nhìn vào kết quả ở đây http://pastebin.com/raw/FghmXkby nó không đúng .. luôn luôn cùng một kết quả sai. – barlop

Trả lời

50

Nhược điểm ider mã này:

List<Action> actions = new List<Action>(); 

for (int i=0; i < 10; i++) 
{ 
    actions.Add(() => Console.WriteLine(i)); 
} 

foreach (Action action in actions) 
{ 
    action(); 
} 

Bạn mong đợi điều này để in? Câu trả lời rõ ràng là 0 ... 9 - nhưng thực ra nó in 10, mười lần. Đó là bởi vì chỉ có một biến được tất cả các đại biểu nắm bắt. Đó là loại hành vi đó là bất ngờ.

EDIT: Tôi vừa thấy bạn đang nói về VB.NET chứ không phải là C#. Tôi tin rằng VB.NET có các quy tắc phức tạp hơn, do các biến cách duy trì giá trị của chúng trong các lần lặp. This post by Jared Parsons cung cấp một số thông tin về các loại khó khăn liên quan - mặc dù nó trở lại từ năm 2007, vì vậy hành vi thực tế có thể đã thay đổi kể từ đó.

+6

Trong hai từ: lambda không được đánh giá là cần thiết trong khi lặp lại, và khi chúng được gọi là biến lặp có thể nằm ngoài phạm vi, không được phân bổ hoặc với giá trị cuối cùng (thậm chí vượt quá giới hạn vòng lặp). – BertuPG

+8

@BertuPG: Đó là hai từ mà bạn đang nghĩ đến? ;) –

+0

@Joh: oh ... yeah ... vì vậy hãy để tôi thay thế "từ" bằng "cụm từ" ^^ – BertuPG

6

Giả sử bạn có nghĩa là C# tại đây.

Đó là do cách trình biên dịch thực hiện đóng. Việc sử dụng biến lặp có thể gây ra sự cố khi truy cập vào một đóng cửa đã sửa đổi (lưu ý rằng tôi có thể nói 'có thể' không 'sẽ gây ra vấn đề bởi vì đôi khi nó không xảy ra tùy thuộc vào phương pháp nào khác, và đôi khi bạn thực sự muốn truy cập đóng cửa đã sửa đổi). Thông tin

thêm:

http://blogs.msdn.com/abhinaba/archive/2005/10/18/482180.aspx

Thậm chí biết thêm:

http://blogs.msdn.com/oldnewthing/archive/2006/08/02/686456.aspx

http://blogs.msdn.com/oldnewthing/archive/2006/08/03/687529.aspx

http://blogs.msdn.com/oldnewthing/archive/2006/08/04/688527.aspx

+1

Nó không phải là "một đóng cửa cho mỗi phương pháp" - nó phức tạp hơn thế. –

+0

Vâng, tôi nhận ra rằng đọc kém - tôi đã cố gắng diễn giải tình hình một cách nhanh chóng (Raymond giải thích sâu hơn). Đã xóa cụm từ vi phạm để mọi người có thể xem các liên kết thông tin khác. –

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