簡単に言うと、使用されるすべての型の親型を使用することで、配列内のさまざまな型パラメーターを使用してジェネリックスを格納できるようにしたいと思います。MSDNは、ジェネリックスは不変型であるため不可能であると述べましたが、4.0フレームワーク以降、これが変更されたとのコメントがありました。
これが私がやりたいことの基本的な例です:
public class Animal
{
}
public class Dog : Animal
{
}
public class Cat : Animal
{
}
public class MyGeneric<T>
{ }
public class MyInheritedGeneric<T> : MyGeneric<T>
{ }
static void Main(string[] args)
{
MyGeneric<Animal>[] myGenericArray = new MyGeneric<Animal>[]
{
new MyGeneric<Dog>(),
new MyInheritedGeneric<Cat>()
};
}
これにより、同様のエラーが返されます。
Cannot implicitly convert type
'InheritanceTest.Program.MyGeneric<InheritanceTest.Program.Dog>' to
'InheritanceTest.Program.MyGeneric<InheritanceTest.Program.Animal>'
Cannot implicitly convert type
'InheritanceTest.Program.MyInheritedGeneric<InheritanceTest.Program.Cat>'
to 'InheritanceTest.Program.MyGeneric<InheritanceTest.Program.Animal>'
タイプの親クラスを使用してジェネリックスを配列に格納する方法はありますか、それともこれは単に不可能ですか?私はそれが可能であることを本当に望んでいます、さもなければそれは私のプログラムを悪夢にするでしょう...
編集:もう少しコンテキスト!
ゲームで敵を生成するクラスを作っています。私はそれらをテンプレートと呼んでいます(実際のテンプレートクラスとは関係ありません。ブループリントまたはファクトリーと呼んでもかまいません)。敵のコンストラクターはテンプレートを受け取り、それを使用して自身の値を決定します。ゲームが読み込まれると、テンプレートを使用して、Generate()関数を使用してすべての敵を生成します。この関数は、生成するように割り当てられている対応するタイプの配列を返します。テンプレートを使用して作成されるすべてのオブジェクトには、テンプレートを唯一のパラメーターとして使用するコンストラクターが必要です。
public class Template<T>
{
protected static Random random = new Random();
protected int _amount;
public int Amount
{
get { return _amount; }
}
public virtual T CreateInstance()
{
return (T)Activator.CreateInstance(typeof(T), this);
}
public virtual T[] Generate()
{
T[] objects = new T[Amount];
for (int i = 0; i < Amount; ++i)
objects[i] = CreateInstance();
return objects;
}
}
これは、実際の敵のクラスとテンプレートを含むBasicZombie.csファイルの要約です。
class Tpl_BasicZombie : Tpl_Enemy<BasicZombie>
{
public Tpl_BasicZombie()
{
_hp = 4;
_speed = 3;
_amount = 10;
}
}
class BasicZombie : GroundEnemy
{
public BasicZombie(Tpl_BasicZombie template)
: base(template, TextureManager.Get("zombie_base"), 1, 8)
{ }
public void StuffHappens()
{ }
}
ゲームをロードするとき、私はそれらから敵をロードするために配列内のすべてのテンプレートを調べたいと思います。これは手動で実行できることはわかっていますが、新しいタイプの敵を作成するたびに、手動でコードに追加する必要があります(したがって、おそらく2回以上忘れてしまいます)。
私の2つのオプションは次のとおりです。1-ジェネリックを使用すると、上記の問題が発生します。2-非ジェネリックを使用し、型を内部に格納します。これにより、戻り型のGenerate()関数が固定されます。これは、生成関数がオブジェクトの配列を出力することを意味します。この配列は、テンプレートが敵の配列を生成するたびに適切なタイプに変換する必要があります。
私の頭の中には、これらすべてにエレガントな解決策があることを伝えるスペースがあります。それが正しいことを願っています。