【C#】List.ForEachとArray.ForEachの使い方:foreachループとの違い

目次

foreachループとForEachメソッド

C#で配列(T[])やList<T>(ジェネリックリスト)に含まれるすべての要素に対して、何らかの処理を順番に行いたい場合、foreachループ構文を使用するのが最も標準的な方法です。

var items = new List<string> { "A", "B", "C" };
foreach (var item in items)
{
    Console.WriteLine(item);
}

このforeachループと非常によく似た機能として、List<T>クラスとArrayクラスは、ForEachという名前のメソッドを提供しています。このメソッドは、引数としてAction<T>デリゲート(通常はラムダ式)を受け取り、反復処理をより簡潔なメソッド呼び出しの形式で記述できます。

この記事では、List<T>.ForEachArray.ForEachの基本的な使い方と、foreachループ構文との違いについて解説します。


1. List<T>.ForEach(Action<T> action) メソッド

List<T>が持つインスタンスメソッドです。リストの各要素を引数として、指定されたAction<T>(戻り値のない処理)を実行します。

コード例 (List<T>)

List<string>(タスク一覧)の各要素をForEachメソッドで処理し、大文字に変換して出力する例です。

using System;
using System.Collections.Generic;

public class ListForEachExample
{
    public static void Main()
    {
        // 1. List<string> を初期化
        var taskList = new List<string>
        {
            "Design Database",
            "Implement API",
            "Write Unit Tests"
        };

        Console.WriteLine("--- Task List (Upper Case) ---");

        // 2. ForEach メソッドにラムダ式を渡す
        // リストの各要素 (task) がラムダ式に渡され、処理が実行される
        taskList.ForEach(task => Console.WriteLine(task.ToUpper()));
    }
}

出力結果:

--- Task List (Upper Case) ---
DESIGN DATABASE
IMPLEMENT API
WRITE UNIT TESTS

2. Array.ForEach(T[] array, Action<T> action) メソッド

Arrayクラスが持つ静的メソッドです。List<T>ForEachとは異なり、インスタンスから呼び出すのではなく、Array.ForEachの第1引数に対象の配列を渡します。

コード例 (Array)

int[](スコア配列)の各要素に対して、10点のボーナスを加算した結果を出力する例です。

using System;

public class ArrayForEachExample
{
    public static void Main()
    {
        // 1. int[] (配列) を初期化
        int[] scores = { 85, 92, 78, 100 };

        Console.WriteLine("--- Scores with Bonus (10) ---");

        // 2. Array.ForEach 静的メソッドを使用
        // 第1引数に対象の配列、第2引数に処理(ラムダ式)を渡す
        Array.ForEach(scores, score =>
        {
            int bonusScore = score + 10;
            Console.WriteLine(bonusScore);
        });
    }
}

出力結果:

--- Scores with Bonus (10) ---
95
102
88
110

foreachループ構文との比較と注意点

ForEachメソッドはコードを簡潔にできますが、foreachループ構文とは異なる重要な制約があります。

1. break / continue が使用できない

ForEachメソッドの引数として渡されるラムダ式(=> { ... })は、それ自体が独立したメソッド(関数)として扱われます。

そのため、foreachループ構文のようにbreak(ループ全体の中断)やcontinue(現在の回のスキップ)を使用して、ForEachメソッドの反復処理自体を制御することはできません

  • ForEachが適している場面: 全要素に対して、中断やスキップの必要がない単純な処理(Console.WriteLineなど)を行う場合。
  • foreachループが適している場面: ループの途中で特定の条件(例: if (item == null))に基づいてbreakcontinueを行う必要がある、より複雑なロジック。

2. LINQ との混同

ForEachメソッドは、LINQ(Where, Select, OrderByなど)のメソッドチェーンの一部ではありませんForEachIEnumerable<T>インターフェースには定義されておらず、List<T>クラス(とArrayクラス)に固有のメソッドです。

ForEachSelect(射影)とは異なり、戻り値がvoidであり、既存のコレクションの各要素に対して「副作用」(Console.WriteLineなど)を起こすか、リスト自体を変更する(List<T>の要素が参照型の場合)ために使用されます。


まとめ

List<T>.ForEachおよびArray.ForEachは、foreachループ構文の代替となるメソッド形式の反復処理です。

ラムダ式を利用することでコードが簡潔になるメリットがありますが、breakcontinueによるループ制御ができないという制約もあります。単純な全要素処理にはForEachを、複雑な制御が必要な場合はforeachループ構文を、と使い分けるのが良いでしょう。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次