【C#】ジェネリッククラスとは

ジェネリッククラスとは

ジェネリッククラスとは、「特定のデータ型に固有ではない操作をカプセル化」するクラスです。

■公式ドキュメント
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/

クラス内のメソッドは同じで、型だけが違うクラスを一緒にできるということです。

 

ジェネリッククラスを使用しない実装

C#で「int型」と「float型」を使用した処理を書いてみます。

using System;

namespace c_generic
{
    public class NormalCalculation
    {
        public int Calculation1(int a)
        {
            return a;
        }

        public float Calculation2(float b)
        {
            return b;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var normalCal = new NormalCalculation();
            int normalCal1 = normalCal.Calculation1(10);
            float normalCal2 = normalCal.Calculation2(10.5f);

            Console.WriteLine(normalCal1.ToString());
            Console.WriteLine(normalCal2.ToString());
        }
    }
}

実行結果:
10
10.5

ジェネリッククラスを使用しない場合、int型とfloat型のメソッドをそれぞれ用意する必要があります。

ここでジェネリッククラスを使用することにより、簡略化することができます。

 

ジェネリッククラスを用いた実装

using System;

namespace c_generic
{
    public class TCalculation  // ジェネリッククラス 
    {
        public T GenericCalculation(T c)
        {
            return c;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
          // 呼び出し側で型を指定
            var genericCal1 = new TCalculation<int>();
            var genericCal2 = new TCalculation<float>();

            int genericInt = genericCal1.GenericCalculation(20);
            float genericFloat = genericCal2.GenericCalculation(20.5f);

            Console.WriteLine(genericInt.ToString());
            Console.WriteLine(genericFloat.ToString());
        }
    }
}

実行結果:
20
20.5

ジェネリッククラスを用いると、メソッドを複数記述しなくてもint型とfloat型を扱えるようになります。

このように、ジェネリッククラスを使用することで、型制約がなくなることが特徴です

 

ジェネリッククラスを使う際に注意点

ジェネリッククラスは、型制約がなくなる反面、型に依存しているメソッドの呼び出しができません

型に依存しているメソッドを呼び出したい場合は、ジェネリッククラスに制約を設ける必要があり、クラス名に「where句」を付けて宣言します。

この制約には型制約やインターフェース、継承などの指定方法があり、複数の制約を組み合わせて実装することも可能です。

   public class TCalculation where T : struct
    {
        public T GenericCalculation(T c)
        {
            return c;
        }
    }

上記の例は、ジェネリッククラスに値型であるという制約を加えています。

where 変数名 : 制約条件

カンマ区切りで複数指定が可能です。

主な制約条件は「struct(値型)」、「class(参照型)」、「クラス名(型継承)」、「インターフェース名(インターフェースの実装)」となります。

 

おすすめ書籍

■C#を学習し始めた方向け
やさしいC 第3版 (「やさしい」シリーズ)

1週間でCの基礎が学べる本

確かな力が身につくC「超」入門 第2版 (Informatics&IDEA)