vendredi 30 juin 2017

Create a new instance of a generic type at runtime without type checking

The following design is simply a template to show my problem.

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();
    }
}

The problem is that next time I add a new hero, I would have to add another if statement in the LevelUp function and this becomes messy.

I know I can use Activator.CreateInstance to create a new instance however there are two problems, 1. all objects are immutable. 2. number and type of parameters in the constructor.

Could anyone please suggest a solution to this problem?





Aucun commentaire:

Enregistrer un commentaire