在运行时创建泛型类型的新实例,而不进行类型检查

时间:2017-06-30 09:48:09

标签: c# .net reflection interface solid-principles

以下设计只是一个显示我问题的模板。

public interface IHero
{
    string Name { get; }
    int Level { get; }
}
public interface IWarlock : IHero
{
    string MagicType { get; }
}
public interface IKnight : IHero
{
    string CommandHierarchy { get; } 
}
public class Warlock : IWarlock, IHero
{

    string IWarlock.MagicType { get { throw new NotImplementedException(); } }

    string IHero.Name { get { throw new NotImplementedException(); } }

    int IHero.Level { get { throw new NotImplementedException(); } }

    public Warlock(string name, int level, string magicType)
    {

    }
}
public class Knight : IKnight, IHero
{

    string IKnight.CommandHierarchy { get { throw new NotImplementedException(); } }

    string IHero.Name { get { throw new NotImplementedException(); } }

    int IHero.Level { get { throw new NotImplementedException(); } }

    public Knight(string name, int level, string commandHierarchy)
    {

    }
}
public class NullHero : IHero
{

    public string Name { get { return string.Empty } }

    public int Level { get { return -1; } }
}

class Program
{
    static void Main(string[] args)
    {

    }
    //Increments the hero's level.
    static IHero LevelUp(IHero hero)
    {
        if (hero is IWarlock)
            return new Warlock(hero.Name, hero.Level + 1, (hero as IWarlock).MagicType);
        else if (hero is IKnight)
            return new Knight(hero.Name, hero.Level + 1, (hero as IKnight).CommandHierarchy);
        else
            return new NullHero();
    }
}

问题是下次我添加一个新的英雄时,我必须在LevelUp函数中添加另一个if语句,这会变得混乱。

我知道我可以使用Activator.CreateInstance创建一个新实例但是有两个问题,1。所有对象都是不可变的。 2.构造函数中参数的数量和类型。

有人可以建议解决这个问题吗?

编辑: 是的,评论部分的每个人都是正确的。我可以在IHero界面中添加LevelUp作为定义。

也许我选择了错误的概念来传达我的问题,但让我们假设我想要在模板中显示的外部处理LevelUp。有没有办法解决我唯一的问题,即创建IHero类型的新实例而不必进行类型检查?

1 个答案:

答案 0 :(得分:0)

由于您的对象是不可变的,并且您希望在每个英雄的特定类中保持升级逻辑,因此最好将LevelUp方法添加到IHero界面。

public interface IHero
{
    string Name { get; }
    int Level { get; }
    IHero LevelUp();
}

在你的特定英雄课程中,你会像这样实现LevelUp方法。

public IHero LevelUp()
{
    return new Warlock(this.Name, this.Level + 1, this.MagicType);
}

你可以保持你的静态水平功能以实现向后兼容,但你应该重构它。

static IHero LevelUp(IHero hero)
{
    return hero.LevelUp();
}