从字符串实例化一个Inherited类

Lea*_*ona 2 c# oop inheritance

我想知道是否有一种简单的方法来实例化一个继承的对象(知道类名).

假设我有

public abstract Monster{
    public string name;
    public string specie;
    public Stats baseStats;
    public string imgDir;
}
Run Code Online (Sandbox Code Playgroud)

public Specie1 : Monster{
    public new string specie = "Specie1";
    public new Stats baseStats = {1,2,3,4,5};
    public new imgDir = "dir/specie1.png";
    public Specie1(string n){
        name = n;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的目标是从保存的文件加载怪物,只用一个物种测试它,我做以下事情:

Monster[0] = new Specie1("foo");
Run Code Online (Sandbox Code Playgroud)

但是,如果我有很多物种,有没有办法一般地实例化?

例如:

string specie = loadSpecie();
Monster[] = new specie("foo");
Run Code Online (Sandbox Code Playgroud)

我希望有一种方法可以做到这一点,而无需在任何地方创建大量的开关和ifs.

我在考虑创建一个构造函数

Monster(string species,string name){
    if(species == "Specie1"){
        return new Specie1(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

但我认为这将是可怕的编程,并且根本不可扩展.

Joh*_*ger 5

您可以使用工厂方法来实例怪物子类.

public abstract Monster
{
    public string name;
    public string specie;
    public Stats baseStats;
    public string imgDir;

    public static Monster CreateMonster(string monster)
    {
        Type[] types = GetTypeInfo().Assembly.GetTypes();
        Type monsterType = types.FirstOrDefault(t => t.Name.ToLower().Equals(monster.ToLower()));

        if (monsterType == null)
            throw new InvalidOperationException("The given monster does not have a Type associated with it.");

        return Activator.CreateInstance(monsterType) as Monster;
    }
}

public class Cat : Monster
{
}
Run Code Online (Sandbox Code Playgroud)

CreateMonster方法查找当前程序集中的所有类型,并创建它找到的第一个Type的实例,该实例的名称与提供的怪物名称相匹配.您可能希望包含一些逻辑,以便它不会尝试实例化抽象类,并确保该类型实际上是一个子类Monster.

我个人可能会用一个为每个类提供友好名称的属性来装饰怪物子类.我会将属性值保存到文件中,并保存到第一个具有与怪物名称匹配的属性的Type.我也只会GetTypes()打一次电话.您应该将结果缓存在Monster类的私有静态字段中.这样,您只使用一次反射.无论如何,上面的代码都可以使用,可以像这样使用:

Monster cat = Monster.CreateMonster("Cat");
Run Code Online (Sandbox Code Playgroud)