长话短说,我希望能够通过对所有使用的类型使用父类型,在数组中使用不同类型参数存储泛型。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()
{ }
}
加载游戏时,我想遍历数组中的所有模板以从中加载敌人。我知道我可以手动执行此操作,但每次创建新类型的敌人时,我都需要手动将其添加到代码中(因此可能会忘记不止一次)。
我的两个选择是:1-使用泛型,然后出现上述问题。2- 使用非泛型,并将类型存储在其中,这将锚定返回类型 Generate() 函数。这意味着 generate 函数将输出一个对象数组,该数组需要在模板每次生成敌人数组时转换为合适的类型。
我的脑海中有一个空间告诉我有一个优雅的解决方案来解决这一切,我希望它是正确的!