首页 > 解决方案 > C#:从已知数量的构造函数中调用随机构造函数的聪明方法是什么?

问题描述

在我的游戏中,我有不同的敌人。当我创建一个地牢时,我希望游戏随机决定从玩家那里放入哪个敌人。每个敌人都是用自己的构造函数创建的,例如:

Ogre Ogre1 = new Ogre(level 1);

我用我在别处定义的方法来与敌人作战

fight(enemy);

现在我知道我可以通过执行以下操作来调用随机构造函数:

int i = new Random.Next(1,5)

然后这个:

if (i= 1)
{Ogre Ogre1 = new Ogre(level 1);
Fight(Ogre1);
}

else if (i=2)
{ Skeleton Skeleton 1 = new Skeleton (level 1);
....

但是,假设我最终会有很多敌人,这似乎很乏味。有没有更聪明的方法来做到这一点,例如,我可以将可能的敌人存储在列表中,然后从列表中调用构造函数吗?

编辑:下面的答案似乎给了我我所需要的!奇怪的是,如果我尝试直接实现解决方案,它只在我输入 lambda 表达式时才有效:

    static Func<int, Enemy>[] EnemyFactory = new[] 
    {
        (level) => (Enemy) new Ogre(level),
        (level) => (Enemy) new Skeleton(level)
    };

我得到错误代码 CS0826 没有找到隐式类型数组的最佳类型。

但是,如果我输入 lambda 函数,它会突然起作用!

        static Func<int, Enemy>[] EnemyFactory = new Func<int, Enemy>[] 
    {
        (level) => (Enemy) new Ogre(level),
        (level) => (Enemy) new Skeleton(level)
    };

标签: c#constructor

解决方案


制作一个类型的“敌人工厂”数组Func<IEnemy>并从该数组中选择一个随机工厂。

这是一个潜在实现的框架:

interface IEnemy ...
class Ogre : IEnemy ...
class Skeleton : IEnemy ...

static Func<IEnemy>[] EnemyFactory = new Func<IEnemy>[] {
    () => (IEnemy)new Ogre()
,   () => (IEnemy)new Skeleton()
,   ...
};

如果要将参数传递给构造函数,它们要么必须相同,要么需要将所有参数的“超集”传递给仿函数。例如,如果您需要将一个类型的对象传递Level给所有构造函数,则更改将如下所示:

static Func<Level,IEnemy>[] EnemyFactory = new Func<Level,IEnemy>[] {
    (level) => (IEnemy)new Ogre(level)
,   (level) => (IEnemy)new Skeleton(level)
,   ...
};

推荐阅读