C# ジェネリッククラスの定義

ジェネリッククラスを自分で定義することで、型に依存しない再利用可能なデータ構造やロジックを作成できます。

基本的な定義方法

クラス名の後に <T> を付けることで、型パラメータを持つクラスになります。

public class Box&lt;T&gt;
{
    private T _content;

    public void Put(T item)
    {
        _content = item;
    }

    public T Get()
    {
        return _content;
    }
}

T は型パラメータで、クラスを使う時に具体的な型に置き換わります。

ジェネリッククラスの使用

// int 型を格納する Box
var intBox = new Box&lt;int&gt;();
intBox.Put(42);
int number = intBox.Get(); // 42

// string 型を格納する Box
var stringBox = new Box&lt;string&gt;();
stringBox.Put("Hello");
string message = stringBox.Get(); // "Hello"

同じ Box クラスが、int 用にも string 用にも使えています。

複数の型パラメータ

型パラメータは複数持つことができます。

public class Pair&lt;TFirst, TSecond&gt;
{
    public TFirst First { get; set; }
    public TSecond Second { get; set; }

    public Pair(TFirst first, TSecond second)
    {
        First = first;
        Second = second;
    }
}
var pair = new Pair&lt;string, int&gt;("Age", 25);
Console.WriteLine($"{pair.First}: {pair.Second}"); // Age: 25

実用的な例:スタックの実装

ジェネリッククラスの実用例として、簡単なスタックを実装してみます。

public class SimpleStack&lt;T&gt;
{
    private List&lt;T&gt; _items = new List&lt;T&gt;();

    public void Push(T item)
    {
        _items.Add(item);
    }

    public T Pop()
    {
        if (_items.Count == 0)
            throw new InvalidOperationException("スタックが空です");

        T item = _items[_items.Count - 1];
        _items.RemoveAt(_items.Count - 1);
        return item;
    }

    public int Count =&gt; _items.Count;
}
var stack = new SimpleStack&lt;string&gt;();
stack.Push("A");
stack.Push("B");
stack.Push("C");

Console.WriteLine(stack.Pop()); // C
Console.WriteLine(stack.Pop()); // B

型パラメータの命名規則

型パラメータには慣習的な命名規則があります。

T

単一の型パラメータに使う汎用的な名前。

TKey, TValue

Dictionary のようにキーと値を扱う場合。

TInput, TOutput

入力と出力を区別する場合。

TElement

コレクションの要素型を表す場合。

型パラメータ名は大文字の T で始めるのが一般的です。説明的な名前を付けることで、コードの意図が伝わりやすくなります。

public class Repository&lt;TEntity&gt;
{
    public void Save(TEntity entity) { /* ... */ }
    public TEntity FindById(int id) { /* ... */ return default!; }
}

ジェネリッククラスを活用することで、型安全かつ再利用可能なコンポーネントを設計できます。