こんにちは。受託開発担当(ここでは雑記担当)のMasaです。

前々回前回に引き続き C#Java におけるジェネリックなクラスについてを検証します。

まずは C# です。前々回作成した MyObject1 MyObject2 クラスにプロパティとデバッグ用メソッドを追加します。

public class MyObject1 : MyObject
{
    public MyObject1() : base() { }

    public MyObject1(string name, string company) : base(name)
    {
        this.Company = company;
    }

    public string Company { get; private set; }

    public override string ToString()
    {
        return "名前は、" + this.Name + "です。企業は、" + this.Company + "です。";
    }
}

public class MyObject2 : MyObject
{
    public MyObject2() : base() { }

    public MyObject2(string name, string value) : base(name)
    {
        this.Value = value;
    }

    public string Value { get; private set; }

    public override string ToString()
    {
        return "名前は、" + this.Name + "です。値は、" + this.Value + "です。";
    }
}

次はジェネリックなクラスです。適当な仕組みが思いつかなかったのでイベントリスナー風の何かを作成します。
とりあえず適当なインタフェースを作成します。

public interface MyObjectContainer<T> where T : MyObject, new()
{
    T GetInstance();
}

上記インタフェースを実装したクラスを追加します。ファイルを分けるのが面倒なので、前々回作成した Test クラスにプライベートクラスを追加しちゃいます。

private class MyObject1Container : MyObjectContainer<MyObject1>
{
    #region MyObjectContainer<MyObject1> メンバ
    public MyObject1 GetInstance()
    {
        return new MyObject1("C#", "Microsoft");
    }
    #endregion
}

private class MyObject2Container : MyObjectContainer<MyObject2>
{
    #region MyObjectContainer<MyObject2> メンバ
    public MyObject2 GetInstance()
    {
        return new MyObject2("C#", "3.0");
    }
    #endregion
}

MyObjectContainer クラスを格納するリストを追加します。ちょっとごちゃごちゃしてきたのでクラスを分けます。

public class MyObjectTest
{
    private IList MyObjectContainerList { get; set; }

    public void AddMyObjectContainer<T>(MyObjectContainer<T> container) where T : MyObject, new()
    {
        if (MyObjectContainerList == null)
            MyObjectContainerList = new ArrayList();
        MyObjectContainerList.Add(container);
    }

    public void Execute<T>() where T : MyObject, new()
    {
        // リストから指定された型パラメータを持つ Container クラスを取得し、クラス情報を出力します。
        IEnumerable<MyObjectContainer<T>> list = MyObjectContainerList.OfType<MyObjectContainer<T>>();
        if (list.Any())
        {
            foreach (MyObjectContainer<T> container in list)
                Console.WriteLine(container.GetInstance().ToString());
        }
    }
}

準備が整ったので、Test クラスにテストメソッドを追加し、実行します。

static void Main(string[] args)
{
    Test test = new Test();

    MyObjectTest myObjectTest = new MyObjectTest();
    myObjectTest.AddMyObjectContainer(new MyObject1Container());
    myObjectTest.AddMyObjectContainer(new MyObject2Container());

    Console.WriteLine("Execute<MyObject1>()が呼ばれるはずです。");
    myObjectTest.Execute<MyObject1>();
    Console.WriteLine("Execute<MyObject2>()が呼ばれるはずです。");
    myObjectTest.Execute<MyObject2>();
}

C#コンソール3

何の苦労もなく実行できます。

次回は Java です。