Listクラス模倣チュートリアル
このチュートリアルでは、C#のList<T>
クラスの基本的な機能を模倣して、自作クラスを実装しながら、リストの内部構造を理解していきます。対象はプログラミングを始めたばかりの方です。
目次
目標
List<T>
の内部構造を理解する。- 配列の動的な拡張や縮小の仕組みを学ぶ。
- ジェネリクス(
T
)の基本概念を掴む。
1. 基本構造の作成
まず、クラスの雛形を作成します。
public class MyList<T>
{
private T[] _items; // 内部でデータを保持する配列
private int _count; // 現在の要素数
// コンストラクタ
public MyList()
{
_items = new T[4]; // 初期容量は4
_count = 0;
}
// プロパティ: 要素数を取得
public int Count
{
get { return _count; }
}
}
解説
T
: ジェネリクスを使用することで、任意の型を格納可能にしています。_items
: リストの内部データを保持する配列です。_count
: 現在リストに格納されている要素数を記録します。
2. 要素を追加する機能の実装
次に、リストに要素を追加するAdd
メソッドを作ります。
public void Add(T item)
{
// 配列の容量が足りない場合は拡張
if (_count == _items.Length)
{
Resize();
}
_items[_count] = item; // 配列に要素を格納
_count++; // 要素数を増やす
}
private void Resize()
{
// 配列を2倍の容量に拡張
T[] newArray = new T[_items.Length * 2];
for (int i = 0; i < _items.Length; i++)
{
newArray[i] = _items[i];
}
_items = newArray;
}
解説
Add
メソッド:- 配列が満杯の場合、
Resize
メソッドで配列を拡張します。 - 空きがある場合は、次の空き位置に値を格納し、カウントを増やします。
- 配列が満杯の場合、
Resize
メソッド:- 配列を現在の2倍の大きさに拡張し、元の要素を新しい配列にコピーします。
3. 要素を取得する機能の実装
次に、要素を取得するGet
メソッドと、インデクサを実装します。
public T Get(int index)
{
if (index < 0 || index >= _count)
{
throw new ArgumentOutOfRangeException(nameof(index), "Index is out of range.");
}
return _items[index];
}
// インデクサ
public T this[int index]
{
get { return Get(index); }
set
{
if (index < 0 || index >= _count)
{
throw new ArgumentOutOfRangeException(nameof(index), "Index is out of range.");
}
_items[index] = value;
}
}
解説
Get
メソッド:- 指定されたインデックスが範囲外の場合に例外をスローします。
- インデクサ:
Get
メソッドを利用して、配列のようにアクセスできるようにします。
4. 要素を削除する機能の実装
次に、指定したインデックスの要素を削除するRemoveAt
メソッドを実装します。
public void RemoveAt(int index)
{
if (index < 0 || index >= _count)
{
throw new ArgumentOutOfRangeException(nameof(index), "Index is out of range.");
}
for (int i = index; i < _count - 1; i++)
{
_items[i] = _items[i + 1];
}
_items[_count - 1] = default(T); // 最後の要素を初期化
_count--; // 要素数を減らす
}
解説
RemoveAt
メソッド:- 削除した要素以降の要素を左に詰めます。
- 最後の要素をデフォルト値にリセットし、要素数を1減らします。
5. テストコードで動作確認
実装が完了したら、以下のようなコードで動作確認を行いましょう。
MyList<int> myList = new MyList<int>();
myList.Add(10);
myList.Add(20);
myList.Add(30);
myList.Add(40);
Console.WriteLine("Count: " + myList.Count); // Count: 4
Console.WriteLine("Item at index 2: " + myList[2]); // Item at index 2: 30
myList.RemoveAt(1);
Console.WriteLine("After removing index 1: " + myList[1]); // After removing index 1: 30
myList[1] = 99;
Console.WriteLine("After setting index 1 to 99: " + myList[1]); // After setting index 1 to 99: 99
練習課題
- 要素が見つかった場合にインデックスを返す
IndexOf
メソッドを実装してみましょう。 - すべての要素を削除する
Clear
メソッドを追加してみましょう。 - 実際の
List<T>
と比較して、足りない機能を考えてみましょう。
まとめ
このチュートリアルでは、List<T>
クラスを模倣することで、動的配列の内部構造や基本的な操作方法を学びました。これを通して、データ構造やジェネリクスの理解を深め、さらに高度なプログラミングへと進む基礎を築きましょう。
ディスカッション
コメント一覧
まだ、コメントがありません