C# ジェネリックス




 
C# では、ジェネリック (Generic) は、プレースホルダーを使用してクラスやメソッドを定義できるようにする仕様であり、コンパイラはコンパイル時にこれらのプレースホルダーを指定された型に置き換えます。属性 ジェネリック クラス (ジェネリック クラス) またはメソッド (ジェネリック) を定義できます。方法)。

 

ジェネリック クラスを定義するには、山括弧<>を使用する必要があります。山括弧は、クラスまたはメソッドをジェネリックとして宣言するために使用されます。概念を理解するのに役立つ簡単な例を次に示します。

 using System;
using System.Collections;

namespace it-kiso.com
{
    // ジェネリッククラスを定義する
    class GenericClass<T>{
        // ジェネリックメソッド
        public GenericClass(T msg){
            Console.WriteLine(msg);
        }
    }
    class Demo
    {
        static void Main(string[] args){
            GenericClass<string> str_gen = new GenericClass<string>("IT基礎");
            GenericClass<int> int_gen = new GenericClass<int>(1234567);
            GenericClass<char> char_gen = new GenericClass<char>('C');
            Console.ReadKey();
        }
    }
} 

許可される結果は次のとおりです。

IT基礎
1234567
C

一般的な機能

ジェネリックは、プログラムの機能を強化するテクノロジと見なされます。ジェネリック クラスとジェネリック メソッドは、非ジェネリック クラスや非ジェネリック メソッドでは実現できない再利用性、型安全性、効率性を兼ね備えています。ジェネリックは、コレクションやコレクションに作用するメソッドとともによく使用され、System.Collections.Generic 名前空間には、いくつかのジェネリック ベースのコレクション クラスが含まれています。以下に、ジェネリックのプロパティのいくつかをまとめます。

  • ジェネリック型を使用すると、コードの再利用を最大限に高め、型の安全性を保護し、パフォーマンスを向上させることができます。
  • ジェネリックの最も一般的な使用法は、コレクション クラスを作成することです。
  • .NET クラス ライブラリには、System.Collections.Generic 名前空間に、System.Collections のコレクション クラスの代わりに使用できるいくつかの新しいジェネリック コレクション クラスが含まれています。
  • 独自の汎用インターフェイス、汎用クラス、汎用メソッド、汎用イベント、および汎用デリゲートを作成できます。
  • ジェネリック クラスを制約して、特定のデータ型のメソッドにアクセスすることもできます。
  • ジェネリック データ型で使用される型に関する情報は、実行時にリフレクションを使用して取得できます。

一般的なメソッド

上の例ではジェネリック クラスを使用しましたが、型パラメータを使用してジェネリック メソッドを宣言することもできます。以下に示すサンプル プログラムを示します。

using System;
using System.Collections.Generic;

namespace it-kiso.com
{
    class Demo
    {
        static void Swap<T>(ref T lhs, ref T rhs)
        {
            T temp;
            temp = lhs;
            lhs = rhs;
            rhs = temp;
        }
        static void Main(string[] args)
        {
            int a, b;
            char c, d;
            a = 10;
            b = 20;
            c = 'I';
            d = 'V';

            // 交換前に値を表示する
            Console.WriteLine("swap を呼び出す前の Int 値:");
            Console.WriteLine("a = {0}, b = {1}", a, b);
            Console.WriteLine("swap を呼び出す前の文字値:");
            Console.WriteLine("c = {0}, d = {1}", c, d);

            // swap を呼び出す
            Swap<int>(ref a, ref b);
            Swap<char>(ref c, ref d);

            // 交換後に値を表示する
            Console.WriteLine("swap を呼び出した後の Int 値:");
            Console.WriteLine("a = {0}, b = {1}", a, b);
            Console.WriteLine("swap を呼び出した後の文字値:");
            Console.WriteLine("c = {0}, d = {1}", c, d);
            Console.ReadKey();
        }
    }
} 

操作の結果は次のようになります。

swap を呼び出す前の Int 値:
a = 10, b = 20
swap を呼び出す前の文字値:
c = I, d = V
swap を呼び出した後の Int 値:
a = 20, b = 10
swap を呼び出した後の文字値:
c = V, d = I

一般的なデリゲート

次の例に示すように、型パラメーターを使用して汎用デリゲートを定義することもできます。

delegate T NumberChanger<T>(T n);

[例] 次の例は、汎用デリゲートの使用方法を示しています。

using System;
using System.Collections.Generic;

namespace it-kiso.com
{
    class Demo
    {
        delegate T NumberChanger<T>(T n);
        static int num = 10;
        public static int AddNum(int p){
            num += p;
            return num;
        }

        public static int MultNum(int q){
            num *= q;
            return num;
        }
        public static int getNum(){
            return num;
        }
        static void Main(string[] args){
            // 委任のインスタンスを作成します
            NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
            NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
            // デリゲートオブジェクトを使用してメソッドを呼び出します
            nc1(25);
            Console.WriteLine("Num の値は: {0}", getNum());
            nc2(5);
            Console.WriteLine("Num の値は: {0}", getNum());
            Console.ReadKey();
        }
    }
} 

操作の結果は次のようになります。

Num の値は: 35
Num の値は: 175

「 C# ジェネリックス」についてわかりやすく解説!絶対に観るべきベスト2動画

【プログラミング講座(C#)】第136回 ジェネリックについて【独り言】
オブジェクト指向最後の難関!コンストラクタを使ってコードを書く!【C#講座/visualstudio#19】