ジェネリクス定義

ジェネリック - C# によるプログラミング入門 | ++C++; // 未確認飛行 C


今までも何度も出てきたあれですね。C++でいうテンプレートです。

兎にも角にも定義してみましょう。

using System;

// ジェネリクスクラス定義
class CClass<T> {
    public T member;
}

class Program {
    static void Main() {
        var cobj1 = new CClass<string> { member = "hoge" };
        var cobj2 = new CClass<int> { member = 1000 };
        
        Console.WriteLine( cobj1.member );
        Console.WriteLine( cobj2.member );
    }
}
$ main
hoge
1000

特に躓くところも無いですね。

ただし以下の例はコンパイルエラーとなります。

using System;

class CClass {
    public string str;
}

class Program {
    // ジェネリクスメソッド定義
    static void Foo<T>(T obj) {
        // objのstrフィールドに参照する
        Console.WriteLine( obj.str );
    }
    
    static void Main() {
        var cobj = new CClass { str = "hoge" };
        
        Foo<CClass>(cobj);
    }
}
$ csc main.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

main.cs(11,26): error CS1061: 'T' に 'str' の定義が含まれておらず、型 'T' の最初の引数を受け付ける拡張メソッドが見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足しています。

これはT型のobjがstrを持ってるかどうか判別できないからエラーになるようです。

これを解決するのにwhereキーワードというのを使います。

    // whereを使いTはCClass及びCClassから派生したクラスだよと宣言する
    static void Foo<T>(T obj)
        where T : CClass {
        Console.WriteLine( obj.str );
    }

これで無事コンパイルが通り処理も実行できます。

whereには他にも色々指定できるのでURLを見ておきましょう。