2011-12-08 11 views
5

Câu hỏi nhanh, Xem mã này:Foreach với Phương pháp mở rộng trên IEnumerable

List<int> result = new List<int>(); 

var list = new List<int> { 1, 2, 3, 4 }; 

list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }); 

Và:

result.Count == 0 //true 

Tại sao result.Add (giá trị) không được thực hiện?

Tuy nhiên điều này không được thực hiện, Một câu hỏi đó là có một cách làm một foreach trên IEnumerable với Extention Method?

Trừ cách này: IEnumerable.ToList().Foreach(p=>...)

+0

bạn cần phải làm đại biểu – MethodMan

+1

@DJKRAZE Đã là đại biểu của nó. –

+0

Tôi đã đăng ví dụ đại biểu của mình dưới đây để sử dụng danh sách.ForEach – MethodMan

Trả lời

17

Tại sao result.Add (giá trị) không được thực hiện?

Điều này là do LINQ sử dụng thực thi hoãn lại. Cho đến khi bạn thực sự liệt kê các kết quả (sự trở lại của Select), các đại biểu sẽ không thực thi.

Để chứng minh, hãy thử như sau:

List<int> result = new List<int>(); 

var list = new List<int> { 1, 2, 3, 4 }; 

var results = list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }); 

foreach(var item in results) 
{ 
    // Just iterating through this will cause the above to execute... 
} 

đó đang được nói, đây là một ý tưởng xấu. LINQ truy vấn không nên có tác dụng phụ nếu bạn có thể tránh nó. Hãy suy nghĩ của Select như một cách để chuyển đổi dữ liệu của bạn, không thực thi mã.

Tuy nhiên, điều này không được thực hiện, Một câu hỏi khác có cách thực hiện foreach trên IEnumerable bằng phương pháp Extention?

Bạn có thể viết phương pháp khuyến nông của riêng bạn:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action) 
{ 
    foreach(var item in items) 
     action(item); 
} 

Tuy nhiên, tôi khuyên bạn không làm điều này. Để biết chi tiết, hãy tham khảo Eric Lippert's post on the subject.

+0

Cảm ơn câu trả lời của bạn, mô tả của bạn đã giải quyết được khó hiểu sự hiểu biết IEnumerable và trì hoãn. –

3

Chọn là lười và thực thi được hoãn lại cho đến khi bạn bắt đầu liệt kê kết quả. Bạn cần phải tiêu thụ resultset bằng cách gọi .ToArray ví dụ hoặc bằng cách lặp qua kết quả:

list.Select(value => 
    { 
     result.Add(value);//Does not work?? 
     return value; 
    }).ToArray(); 
+0

Nếu tôi định sử dụng một phương thức để ép buộc liệt kê, tôi sẽ tìm một phương thức với bộ nhớ liên tục như 'Max()' thay vì 'ToArray()'. –

-1
List<int> result = new List<int>(); 
var list = new List<int> { 1, 2, 3, 4 }; 
list.ForEach(delegate(int sValue) 
{ 
    result.Add(sValue); 
}); 

này hoạt động nhưng tất cả và thêm 1 2 3 4 vào kết quả. Kiểm tra nó ra. Tôi vừa làm.

+0

Tôi đã đề cập: Ngoại trừ cách này: IEnumerable.ToList(). Foreach (p => ...) –