2012-04-24 20 views
44

Tôi bắt đầu tìm kiếm trong Windows 8 gần đây, và thấy rằng một trong những người bạn cũ của tôi dường như đã mất tích.Phương thức List <T> .ForEach() có bị mất không?

Tôi có xu hướng sử dụng phương pháp .ForEach() nhiều hơn tôi sử dụng cấu trúc truyền thống foreach() và tôi nhận ra khá nhanh rằng phương pháp này không khả dụng. Ví dụ, đoạn mã này sẽ không biên dịch theo một ứng dụng metro:

var list = new List<string>(); 

list.ForEach(System.Diagnostics.Debug.WriteLine); 

Tôi đã tìm kiếm để xem nếu tôi có thể tìm thấy bất kỳ cuộc thảo luận về điều này, nhưng đã không thể. Tôi chỉ đang bị nguyền rủa, hay là nó thực sự biến mất?

+3

IEnumerable không bao giờ có phương thức mở rộng ForEach chỉ IList có nó – Clueless

+0

Bạn thưa bạn, là chính xác. Tôi đã được sớm chung chung. Tôi sẽ thay đổi tiêu đề câu hỏi. – Robaticus

+0

Tôi đã phạm sai lầm tương tự - tiêu đề nói IEnumerable nhưng ví dụ rõ ràng là đang cố gắng nó trên một danh sách. Chỉnh sửa: Tiêu đề được cập nhật :-) – yamen

Trả lời

42

It's indeed gone:

Danh sách <T> .ForEach đã được gỡ bỏ trong các ứng dụng phong cách Metro. Trong khi phương pháp có vẻ đơn giản, nó có một số vấn đề tiềm năng khi danh sách bị đột biến bởi phương thức được truyền cho ForEach. Thay vào đó, bạn nên sử dụng vòng lặp foreach.


Wes Haggard | .NET Framework Team (BCL) | http://blogs.msdn.com/b/bclteam/

Rất kỳ lạ, tuy nhiên, nó làm cho một xuất hiện trong documentation, trong đó đâu nó nói rằng phương pháp này không được hỗ trợ trong .NET cho các ứng dụng Windows Store (trước đây là .NET cho các ứng dụng Metro-style) . Có lẽ đây chỉ là một sự giám sát trên một phần của nhóm tài liệu.

+1

@Robaticus: Bạn chỉ có thể thêm phương thức mở rộng của riêng mình để thay thế. Có lẽ tốt nhất nên gọi '.ToList()' trước, sau đó lặp lại điều đó. Không có gì giống như việc lặp lại nguồn trong khi cố gắng biến nó thành hủy hoại ngày của bạn. – Will

+1

@Will - Tôi đồng ý rằng tôi có thể làm điều đó. Nó có lẽ là một thói quen tốt để có được ra khỏi, mặc dù, đặc biệt là khi hiển thị mới lập trình LINQ làm thế nào để làm việc. – Robaticus

16

Một cách khác là để xác định điều đó cho mình tất nhiên:

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) 
{ 
    foreach(T item in enumeration) 
    { 
     action(item); 
     yield return item; 
    } 
} 

Credit: LINQ equivalent of foreach for IEnumerable<T>

(Lưu ý: không phải là một trùng lặp)

+2

Mặc dù điều này thực sự là chấp nhận được, chỉ cần cẩn thận rằng nó không sửa đổi bất kỳ yêu cầu nào của các cuộc gọi IEnumerable trước đó (chẳng hạn như Where hoặc OrderBy). Ngoài ra, nếu bạn muốn tiếp tục chuỗi các cuộc gọi IEnumerable, bạn có thể thay đổi kiểu trả về thành 'IEnumerable 'và' mục trả về lợi nhuận' sau khi thực hiện hành động trên mục. Tuy nhiên, điều này sẽ vẫn làm thay đổi các yếu tố, vì vậy hãy lưu ý rằng những "tác dụng phụ" này có thể làm thay đổi điều tra. – SPFiredrake

+0

Vâng, ForEach chắc chắn nguy hiểm. Tôi đã cập nhật câu trả lời để trả lại 'IEnumerable ' để cho phép tiếp tục chuỗi, nhưng điều này có thể làm cho mọi thứ trở nên nguy hiểm hơn. – yamen

18

Để có được một cảm giác cho lý do tại sao nó có thể không còn bao gồm, đọc bài đăng này của một người làm việc trong nhóm C# tại Microsoft: http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx

Về cơ bản, đó là triết lý. Các tính năng "LINQ" được lấy cảm hứng từ mô hình lập trình chức năng, và phần mở rộng ForEach bay vào mặt của nó ... nó khuyến khích phong cách chức năng kém.

+0

Joel: Tôi nhận được bản gốc sớm và thay đổi tiêu đề để phản ánh Danh sách , thay vì IEnumerable . – Robaticus

+8

"một người làm việc trong nhóm C# tại Microsoft" Làm thế nào tinh tế ... – BoltClock

+9

Ahhh, nó chỉ là anh chàng Lippert một lần nữa. Anh ta biết cái quái gì thế? ;) – Robaticus

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