游戏编程,原型模式:如何将泛型类从C++转换为C#



在这本名为《游戏编程模式》的引人入胜的书中,在原型示例中,作者展示了如何使用泛型类在游戏中生成怪物。

免责声明:作者确实声明,该代码只是为了给一个概念的例子(可能不是完美的(

这是给定示例中的C++代码:

class Spawner
{
public:
virtual ~Spawner() {}
virtual Monster* spawnMonster() = 0;
};
template <class T>
class SpawnerFor : public Spawner
{
public:
virtual Monster* spawnMonster() { return new T(); }
};

调用类将运行:

Spawner* ghostSpawner = new SpawnerFor<Ghost>();

我试着把这个例子翻译成C#,这样它就可以在Unity中的一个场景中进行测试:

public class Spawner<T> {
public virtual Monster SpawnMonster() {
return null;
}
}
class SpawnerTemplate<T> : Spawner { 
public override Monster SpawnMonster() {
return new T();
}
}

场景中的脚本将运行:

var ghost = new Spawner<Ghost>();

Visual Studio不会编译,所以我重写为:

class SpawnerTemplate<T> : Spawner where T : new(){ 
public override Monster SpawnMonster() {
return new T() as Monster;
}
}

调用时仍然存在编译错误

var ghost = new SpawnerTemplate<Ghost>();

必须是具有公共无参数构造函数的非抽象类型,才能将其用作参数

这就是Ghost代码的样子:

public class Ghost : Monster
{
public Ghost (int health, int speed) {
this.health = health;
this.speed = speed;
}
public override Monster Clone() {
return new Ghost(health, speed);
}
}

我从C++到C#的翻译正确吗?

谢谢

不确定这个模式在C#中的有用性,但是:

public class Monster
{
}
public class Ghost : Monster
{
}
public abstract class Spawner
{
public abstract Monster SpawnMonster();
}
public class SpawnerFor<T> : Spawner where T : Monster, new()
{
public override Monster SpawnMonster() { return new T(); }
}

然后:

var spawnerForGhost = new SpawnerFor<Ghost>();
var ghost = spawnerForGhost.SpawnMonster();

C#中的最大限制是,您可以为无参数构造函数(, new()(的存在定义一个约束,如本例所示,但例如,如果您希望new Monster()作为参数(new Monster(location)(接收,则它会崩溃(不能对参数构造函数进行约束。您可以在Monster中明确定义public abstract Initialize(Location location),并从SpawnMonster(Location location)调用它(。

最新更新