コレクションへの要素追加(非破壊的アプローチ)
C#で配列やリストに要素を追加する場合、List<T>.Addメソッドを使用するのが一般的です。しかし、この方法は「元のリストを直接変更する」ため、元のデータを保持したまま新しいシーケンスを作りたい場合には適していません。また、配列(Array)はサイズが固定されているため、そもそもAddができません。
LINQ(Language Integrated Query)の Prepend と Append メソッドを使用すると、元のコレクションを変更することなく、先頭または末尾に新しい要素を追加した新しいシーケンスを簡単に作成できます。
この記事では、これらのメソッドの基本的な使い方と、リスト操作メソッドとの違いについて解説します。
Prepend:先頭に要素を追加
Prependメソッドは、シーケンスの先頭に指定した要素を追加します。
構文: IEnumerable<T> Prepend(T element)
コード例:優先タスクの割り込み
既存のタスクリストの先頭に、緊急タスク(”Urgent Fix”)を割り込ませる例です。
using System;
using System.Collections.Generic;
using System.Linq; // LINQを使用するために必須
public class PrependExample
{
public static void Main()
{
// 既存のタスクリスト
var tasks = new List<string>
{
"Review Code",
"Write Documentation",
"Update Database"
};
// Prepend で先頭に要素を追加
// (tasks 自体は変更されず、新しいシーケンスが返される)
var updatedTasks = tasks.Prepend("【Urgent】 Fix Login Bug");
Console.WriteLine("--- タスク一覧(優先順) ---");
Console.WriteLine(string.Join(Environment.NewLine, updatedTasks));
}
}
出力結果:
--- タスク一覧(優先順) ---
【Urgent】 Fix Login Bug
Review Code
Write Documentation
Update Database
Append:末尾に要素を追加
Appendメソッドは、シーケンスの末尾に指定した要素を追加します。
構文: IEnumerable<T> Append(T element)
コード例:ログの完了メッセージ追加
処理ログの末尾に、完了を示すフッター(”[End of Log]”)を追加する例です。
using System;
using System.Collections.Generic;
using System.Linq;
public class AppendExample
{
public static void Main()
{
// 処理ログ(配列)
string[] logs =
{
"10:00 - System Started",
"10:05 - Connection Established",
"10:10 - Data Sync Complete"
};
// Append で末尾に要素を追加
var completeLogs = logs.Append("10:15 - [End of Log]");
Console.WriteLine("--- システムログ ---");
foreach (var line in completeLogs)
{
Console.WriteLine(line);
}
}
}
出力結果:
--- システムログ ---
10:00 - System Started
10:05 - Connection Established
10:10 - Data Sync Complete
10:15 - [End of Log]
Prepend / Append のチェーン(連鎖)
これらのメソッドはIEnumerable<T>を返すため、メソッドチェーンを使って連続して呼び出すことができます。これにより、ヘッダーとフッターを同時に追加するといった操作が1行で記述できます。
var data = new[] { "Item A", "Item B" };
// 先頭と末尾に同時に追加
var result = data
.Prepend("--- Start ---")
.Append("--- End ---");
Console.WriteLine(string.Join(", ", result));
// 出力: --- Start ---, Item A, Item B, --- End ---
重要な注意点:非破壊的変更とパフォーマンス
PrependとAppendは、LINQの「遅延実行」特性を持っています。メソッドを呼び出した時点ではデータのコピーや移動は発生せず、foreachなどで列挙した瞬間に要素が生成されます。
- メリット: 元のコレクション(配列やリスト)を変更しません。関数型プログラミング的なアプローチに適しています。
- デメリット: あくまで「追加されたように振る舞うシーケンス」を作るだけです。もし、この結果を
List<T>として頻繁に操作したい場合は、最後に.ToList()や.ToArray()を呼び出して実体化する必要があります。
// List<T> として扱いたい場合
List<string> newList = tasks.Prepend("New Task").ToList();
まとめ
PrependとAppendは、C#でシーケンスの前後に要素を追加するためのシンプルで強力なメソッドです。
Prepend(item): 先頭に追加します。Append(item): 末尾に追加します。- 非破壊的: 元のコレクションは変更されません。
配列のようにサイズが固定されているコレクションや、元のデータを汚さずに新しい要素を追加したい場合に、これらのメソッドは非常に役立ちます。
