Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Thực hiện hành động trên từng phần tử List bằng ForEach trong C#

Mục đích

Phương thức List<T>.ForEach(Action<T> action) thực thi delegate action cho **mỗi phần tử** trong list. Tương tự foreach nhưng dạng method, hữu ích cho functional style.

Ví dụ 1: Nhân mỗi số với 10

using System;
using System.Collections.Generic;

public class Demo
{
    public static void MultiplyBy10(int n)
    {
        n *= 10; // Chỉ thay đổi bản cục bộ (value type)
        Console.WriteLine(n);
    }

    public static void Main(string[] args)
    {
        List list = new List { 25, 50, 75, 100, 200, 250, 275, 300 };

        Console.WriteLine("List gốc:");
        foreach (int i in list) Console.WriteLine(i);

        Console.WriteLine("\nList sau ForEach (nhân 10 - chỉ in ra):");
        list.ForEach(MultiplyBy10); // 250, 500, 750...
    }
}

Kết quả

List gốc:
25
50
75
100
200
250
275
300

List sau ForEach (nhân 10 - chỉ in ra):
250
500
750
1000
2000
2500
2750
3000

Ví dụ 2: Trừ 50 từ mỗi phần tử (Lambda)

using System;
using System.Collections.Generic;

public class Demo
{
    public static void Main(string[] args)
    {
        List list = new List { 25, 50, 75, 100, 200, 250, 275, 300 };

        Console.WriteLine("List gốc:");
        foreach (int i in list) Console.WriteLine(i);

        Console.WriteLine("\nForEach với lambda (trừ 50):");
        list.ForEach(x => Console.WriteLine(x - 50));
        // -25, 0, 25, 50, 150, 200, 225, 250
    }
}

⚠️ Lưu ý quan trọng: ForEach KHÔNG sửa đổi List gốc

Với **value type** (int, struct), `action` nhận **bản sao** -> thay đổi bên trong không ảnh hưởng list.

List nums = new List { 1, 2, 3 };
nums.ForEach(x => x = x * 2); // Không thay đổi nums!
Console.WriteLine(string.Join(", ", nums)); // 1, 2, 3

Để sửa đổi list, dùng for loop hoặc List.ConvertAll (tạo list mới):

// Sửa đổi tại chỗ (in-place) - dùng for
for (int i = 0; i < nums.Count; i++) nums[i] *= 2;

// Hoặc tạo list mới
List doubled = nums.ConvertAll(x => x * 2);

Với Reference Type (class)


class Person { public string Name; }
var people = new List { new Person { Name = "A" }, new Person { Name = "B" } };

people.ForEach(p => p.Name = p.Name.ToLower()); // THAY ĐỔI object gốc!
// people[0].Name = "a"

So sánh ForEach vs foreach statement

Đặc điểmList.ForEach(Action)foreach (var x in list)
Sửa đổi element (ref type)Được (thay đổi object)Được
Sửa đổi element (value type)Không (bản sao)Không (bản sao)
Break/ContinueKhông hỗ trợHỗ trợ
Return từ method baoKhông (trong lambda)Hỗ trợ
Hiệu năngGọi delegate (chút overhead)Tối ưu bởi compiler
LINQKhôngDễ chain (.Where().Select())

Khuyến nghị

  • Ưu tiên foreach statement cho readability và control flow.
  • Dùng ForEach cho side-effect đơn giản (logging, add to another collection).
  • Tránh logic phức tạp trong ForEach.