次の方法で共有


ジェネリック クラスとメソッド

ジェネリックでは、.NET に型パラメーターの概念が導入されています。 ジェネリックを使用すると、コードでクラスまたはメソッドを使用するまで、1 つ以上の型パラメーターの指定を延期するクラスとメソッドを設計できます。 たとえば、ジェネリック型パラメーター Tを使用すると、次に示すように、ランタイム キャストやボックス化操作のコストやリスクを発生させることなく、他のクライアント コードで使用できる 1 つのクラスを記述できます。

// Declare the generic class.
public class GenericList<T>
{
    public void Add(T item) { }
}

public class ExampleClass { }

class TestGenericList
{
    static void Main()
    {
        // Create a list of type int.
        GenericList<int> list1 = new();
        list1.Add(1);

        // Create a list of type string.
        GenericList<string> list2 = new();
        list2.Add("");

        // Create a list of type ExampleClass.
        GenericList<ExampleClass> list3 = new();
        list3.Add(new ExampleClass());
    }
}

ジェネリッククラスとメソッドは、再利用性、型の安全性、および効率性を兼ね備えており、これらは非ジェネリックのクラスやメソッドでは実現できないものです。 ジェネリック型パラメーターは、コンパイル時に型引数に置き換えられます。 前の例では、コンパイラは Tintに置き換えます。 ジェネリックは、コレクションおよびそれらに対して動作するメソッドで最もよく使用されます。 System.Collections.Generic名前空間には、いくつかのジェネリック ベースのコレクション クラスが含まれています。 ArrayListなどの非ジェネリック コレクションは推奨されず、互換性のためにのみ保持されます。 詳細については、.NET の「ジェネリック」を参照してください。

また、カスタム ジェネリック型とメソッドを作成して、型セーフで効率的な独自の一般化されたソリューションと設計パターンを提供することもできます。 次のコード例は、デモンストレーション用の単純なジェネリック リンク リスト クラスを示しています。 (ほとんどの場合、独自のクラスを作成する代わりに、.NET によって提供される List<T> クラスを使用する必要があります)。型パラメーター T は、一覧に格納されている項目の型を示すために具象型が通常使用される複数の場所で使用されます。

  • AddHead メソッドのパラメーターの型として。
  • 入れ子になった Data クラスの Node プロパティの戻り値の型として使用。
  • 入れ子になったクラスのプライベート メンバー data の型として使用。

T は、入れ子になった Node クラスで使用できます。 GenericList<T>が具象型 (たとえば、GenericList<int>) でインスタンス化されると、Tが発生するたびにintに置き換えられます。

// Type parameter T in angle brackets.
public class GenericList<T>
{
    // The nested class is also generic, and
    // holds a data item of type T.
    private class Node(T t)
    {
        // T as property type.
        public T Data { get; set; } = t;

        public Node? Next { get; set; }
    }

    // First item in the linked list
    private Node? head;

    // T as parameter type.
    public void AddHead(T t)
    {
        Node n = new(t);
        n.Next = head;
        head = n;
    }

    // T in method return type.
    public IEnumerator<T> GetEnumerator()
    {
        Node? current = head;

        while (current is not null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }
}

次のコード例は、クライアント コードがジェネリック GenericList<T> クラスを使用して整数のリストを作成する方法を示しています。 型引数を変更すると、次のコードによって文字列またはその他のカスタム型のリストが作成されます。

// A generic list of int.
GenericList<int> list = new();

// Add ten int values.
for (int x = 0; x < 10; x++)
{
    list.AddHead(x);
}

// Write them to the console.
foreach (int i in list)
{
    Console.WriteLine(i);
}

Console.WriteLine("Done");

ジェネリック型はクラスに限定されません。 上記の例では class 型を使用していますが、ジェネリック interface 型と struct 型 ( record 型を含む) を定義できます。

ジェネリックプログラミングの概要

  • ジェネリック型を使用して、コードの再利用、型の安全性、およびパフォーマンスを最大化します。
  • ジェネリックの最も一般的な用途は、コレクション クラスを作成することです。
  • .NET クラス ライブラリには、 System.Collections.Generic 名前空間に複数のジェネリック コレクション クラスが含まれています。 ジェネリック コレクションは、ArrayList名前空間のSystem.Collectionsなどのクラスではなく、可能な限り使用する必要があります。
  • 独自のジェネリック インターフェイス、クラス、メソッド、イベント、およびデリゲートを作成できます。
  • ジェネリック クラスを制約して、特定のデータ型のメソッドへのアクセスを有効にすることができます。
  • リフレクションを使用して、ジェネリック データ型で使用される型に関する情報を実行時に取得できます。

C# 言語仕様

詳細については、C# 言語仕様のを参照してください。

こちらも参照ください