List<T>の順序反転
C#のList<T>(ジェネリックリスト)に格納された要素の順序を、[A, B, C] から [C, B, A] のように完全に反転させたい場合があります。
List<T>クラスは、この操作を簡単に行うためのReverseというインスタンスメソッドを提供しています。
List<T>.Reverse() メソッド
List<T>.Reverse()メソッドは、そのリストに含まれる要素の順序を完全に反転させます。
重要な特性:インプレース(In-Place)操作
このメソッドの最も重要な特性は、Array.Reverseと同様に**インプレース(In-Place)**で動作する点です。
これは、Reverseメソッドが新しいリストを生成して返すのではなく、メソッドを呼び出した元のList<T>インスタンス自体を直接変更する(中身を書き換える)ことを意味します。このメソッドの戻り値はvoid(何も返さない)です。
コード例1:List<int>(数値)の逆順
List<int>(整数のリスト)の順序をReverseメソッドで反転させる例です。
using System;
using System.Collections.Generic;
public class ListReverseValueTypeExample
{
public static void Main()
{
// 1. 元のリストを定義
var recentScores = new List<int> { 100, 85, 92, 70, 55 };
Console.WriteLine("--- 実行前 ---");
PrintList(recentScores); // 100, 85, 92, 70, 55
// 2. Reverse メソッドを呼び出し (元のリストが変更される)
recentScores.Reverse();
Console.WriteLine("\n--- 実行後 ---");
PrintList(recentScores); // 55, 70, 92, 85, 100
}
// リストの要素を出力するヘルパーメソッド
private static void PrintList(List<int> list)
{
Console.WriteLine(string.Join(", ", list));
}
}
出力結果:
--- 実行前 ---
100, 85, 92, 70, 55
--- 実行後 ---
55, 70, 92, 85, 100
コード例2:List<string>(文字列)の逆順
stringなどの参照型リストに対しても、動作は全く同じです。
using System;
using System.Collections.Generic;
public class ListReverseReferenceTypeExample
{
public static void Main()
{
// 1. 元の文字列リストを定義
var taskQueue = new List<string>
{
"Task A: Initialize",
"Task B: Process Data",
"Task C: Generate Report"
};
Console.WriteLine("--- 実行前 (キューの順序) ---");
PrintList(taskQueue);
// 2. Reverse メソッドを呼び出し
taskQueue.Reverse();
Console.WriteLine("\n--- 実行後 (スタックの順序) ---");
PrintList(taskQueue);
}
// リストの要素を出力するヘルパーメソッド
private static void PrintList(List<string> list)
{
foreach (var item in list)
{
Console.WriteLine(item);
}
}
}
出力結果:
--- 実行前 (キューの順序) ---
Task A: Initialize
Task B: Process Data
Task C: Generate Report
--- 実行後 (スタックの順序) ---
Task C: Generate Report
Task B: Process Data
Task A: Initialize
補足:LINQのReverse()との明確な違い
List<T>のReverse()メソッド(インスタンスメソッド)と、LINQ(System.Linq)が提供するReverse()拡張メソッド(IEnumerable<T>に対するメソッド)は、名前が同じですが動作が全く異なります。
myList.Reverse()(本記事のList<T>インスタンスメソッド)- 動作: 元のリストを直接変更します(インプレース)。
- 戻り値:
void(何も返しません)。
myList.AsEnumerable().Reverse()(LINQの拡張メソッド)- 動作: 元のリストは変更しません。
- 戻り値: 要素が逆順になった**新しいシーケンス(
IEnumerable<T>)**を返します。
List<T>型の変数で.Reverse()を呼び出すと、C#は常にインスタンスメソッド(インプレース版)を優先して呼び出します。もし、元のリストを変更せずに新しい逆順のリストが欲しい場合は、LINQのメソッドを明示的に呼び出す必要があります。
using System.Linq; // LINQ を使用するために必要
List<int> originalList = new List<int> { 1, 2, 3 };
// LINQのReverse()を呼び出し、新しいListを作成する
var newList = originalList.AsEnumerable().Reverse().ToList();
// Console.WriteLine(string.Join(", ", originalList)); // { 1, 2, 3 } (元のリストは変更されない)
// Console.WriteLine(string.Join(", ", newList)); // { 3, 2, 1 } (新しいリスト)
まとめ
List<T>.Reverse()メソッドは、List<T>の要素の順序を「インプレース(in-place)」で、つまり元のリスト自体を直接変更して逆順にするためのメソッドです。
戻り値がvoidであり、新しいリストを生成するわけではない(非破壊的ではない)という点を正確に理解して使用することが重要です。
