2008-12-04 51 views
31

Đầu tiên, tôi biết có các phương thức tắt của lớp chung List<> đã có trong khung làm lặp lại trên List<>.C# Cú pháp - Ví dụ về Biểu thức Lambda - ForEach() trên Danh sách Chung

Nhưng làm ví dụ, cú pháp chính xác để viết phương thức ForEach là gì để lặp qua từng đối tượng của List<> và thực hiện Console.WriteLine(object.ToString()) trên mỗi đối tượng. Nội dung nào đó có số List<> làm đối số đầu tiên và biểu thức lambda làm đối số thứ hai.

Hầu hết các ví dụ tôi đã thấy được thực hiện dưới dạng các phương pháp mở rộng hoặc liên quan đến LINQ. Tôi đang tìm một ví dụ phương pháp đơn giản.

Trả lời

50
public void Each<T>(IEnumerable<T> items, Action<T> action) 
{ 
    foreach (var item in items) 
     action(item); 
} 

... và gọi nó là thusly:

Each(myList, i => Console.WriteLine(i)); 
+0

mát. Bây giờ, cú pháp Func <> mà tôi đã thấy xung quanh sẽ đi vào đâu? – BuddyJoe

+11

Func <> đại biểu là đại biểu chung cho các phương pháp có giá trị trả lại. Hành động <> đại biểu là đại biểu chung cho các phương thức KHÔNG trả về giá trị. Đó là sự khác biệt duy nhất. – TheSoftwareJedi

+1

vì vậy trong trường hợp của bạn, bạn không cần phải trả lại một cái gì đó (từ console.writeline - vì vậy hành động là đủ. – TheSoftwareJedi

26

Trên đây cũng có thể được viết với mã ít hơn như:

new List<SomeType>(items).ForEach(
    i => Console.WriteLine(i) 
); 

Điều này tạo ra một danh sách chung và populates nó với IEnumerable và sau đó gọi các đối tượng danh sách ForEach.

+0

Câu hỏi được hỏi cách viết phương thức (không gọi cách) và chỉ định rằng không muốn sử dụng các phương thức LINQ hoặc Extension. – StriplingWarrior

+0

Điều này thuận tiện, nhưng không phải là chi phí của việc tạo danh sách mới (ngụ ý lặp qua các mục ít nhất một lần bổ sung) thường không đáng giá? – dumdum

+0

Rất hữu ích, cảm ơn bạn. – Bryan

0

Bạn có thể duyệt qua từng chuỗi trong danh sách và thậm chí bạn có thể tìm kiếm toàn bộ chung bằng một câu lệnh đơn giúp việc tìm kiếm dễ dàng hơn.

public static void main(string[] args) 
{ 
List names = new List(); 

names.Add(“Saurabh”); 
names.Add("Garima"); 
names.Add(“Vivek”); 
names.Add(“Sandeep”); 

string stringResult = names.Find(name => name.Equals(“Garima”)); 
} 
22

Đây có phải là những gì bạn đang yêu cầu không?

int[] numbers = { 1, 2, 3 }; 
numbers.ToList().ForEach(n => Console.WriteLine(n)); 
+0

có. điều này tiện dụng và tôi đã sử dụng nó. +1. Vào thời điểm tôi hỏi câu hỏi, tôi nghĩ rằng tôi đã cố gắng để có được một xử lý về cú pháp cơ bản C# lambda khi được sử dụng với Generics. – BuddyJoe

+0

Ok, nhưng chúng ta phải xem xét rằng ToList() là một hoạt động O (n) –

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

... và gọi nó là thusly:

myList.Each(x => { x.Enabled = false; }); 
+1

Một dấu cộng để hiển thị cách thực hiện nhiều thao tác trong mỗi. – Amir978

1

Muốn đưa ra khỏi đó mà không có nhiều lo lắng về việc nếu ai đó cung cấp một câu trả lời như một phương pháp mở rộng bởi vì một phần mở rộng phương pháp chỉ là một cách mát mẻ để gọi một phương pháp dụ. Tôi hiểu rằng bạn muốn câu trả lời mà không sử dụng một phương pháp mở rộng. Bất kể nếu phương thức được định nghĩa là static, instance hoặc extension - kết quả là như nhau.

Mã bên dưới sử dụng mã từ câu trả lời được chấp nhận để xác định phương pháp mở rộng và phương pháp thể hiện và tạo kiểm tra đơn vị để hiển thị đầu ra giống nhau.

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

[TestFixture] 
public class ForEachTests 
{ 
    public void Each<T>(IEnumerable<T> items, Action<T> action) 
    { 
     foreach (var item in items) 
     { 
      action(item); 
     } 
    } 

    private string _extensionOutput; 

    private void SaveExtensionOutput(string value) 
    { 
     _extensionOutput += value; 
    } 

    private string _instanceOutput; 

    private void SaveInstanceOutput(string value) 
    { 
     _instanceOutput += value; 
    } 

    [Test] 
    public void Test1() 
    { 
     string[] teams = new string[] {"cowboys", "falcons", "browns", "chargers", "rams", "seahawks", "lions", "heat", "blackhawks", "penguins", "pirates"}; 

     Each(teams, SaveInstanceOutput); 

     teams.Each(SaveExtensionOutput); 

     Assert.AreEqual(_extensionOutput, _instanceOutput); 
    } 
} 

Khá theo nghĩa đen, điều duy nhất bạn cần làm để chuyển đổi một phương pháp mở rộng cho một phương pháp dụ là loại bỏ các static sửa đổi và các tham số đầu tiên của phương pháp.

Phương pháp này

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

trở thành

public void Each<T>(Action<T> action) 
{ 
    foreach (var item in items) 
    { 
     action(item); 
    } 
} 
Các vấn đề liên quan