How to access array members that are of an interface type c#

Report
Question

Please briefly explain why you feel this question should be reported .

Report Cancel

I am a little lost here.

Basically, I need to access an array item, a string and display it. Here is the code.

namespace Test3_2_Practice
{
public partial class InterfaceImplementation : Form
{
    //Array
    ICombatant[] combatants = new ICombatant[2];

    public InterfaceImplementation()
    {
        InitializeComponent();
    }

    private void btnTest_Click(object sender, EventArgs e)
    {
        combatants[0] = new PlayerCharacter ("Conan" , 500);
        combatants[1] = new MonsterCharacter ("Bob" , 5);
        combatants[2] = new MonsterCharacter ("Snake" , 15);

        string output = "Fighters" + Environment.NewLine;

        for (var i = 0; i < combatants.Length; i++)
        {
            var character = combatants[i];
            output += "Character:" + combatants[i].
        }
    }
}

}

So I have my array, combatants composed of two types of instances. I want to access the name, “Conan” and add it to a string for output. How do I go about doing that? Here is the rest of the code if that helps. Thanks!

namespace Test3_2_Practice
{
//Interface
interface ICombatant
{
    int TakeDamage(int damageAmount);
    string GetHealthDisplay();
}

class PlayerCharacter : ICombatant
{
    private string characterName;
    private int currentHealth;
    private int maxHealth;

    public string CharacterName
    {
        get { return characterName; }
        set { characterName = value; }
    }
    public int CurrentHealth
    {
        get { return currentHealth; }
        set { currentHealth = value; }
    }
    public int MaxHealth
    {
        get { return maxHealth; }
        set { maxHealth = value; }
    }

    public PlayerCharacter(string characterName, int maxHealth)
    {
        CharacterName = characterName;
        CurrentHealth = MaxHealth = maxHealth;
    }

    //Damage Class
    public int TakeDamage(int damageAmount)
    {
        if (damageAmount > currentHealth)
        {
            damageAmount = currentHealth;
            return damageAmount;
        }
        else
        {
            currentHealth = currentHealth - damageAmount;
            return damageAmount;
        }
    }

    //Health Class
    public string GetHealthDisplay()
    {
        return ("Health " + CurrentHealth.ToString() + "/" + MaxHealth).ToString();
    }
}

class MonsterCharacter : ICombatant
{
    private string monsterName;
    private int health;

    public string MonsterName
    {
        get { return monsterName; }
        set { monsterName = value; }
    }
    public int Health
    {
        get { return health; }
        set { health = value; }
    }

    public MonsterCharacter(string monsterName, int health)
    {
        MonsterName = monsterName;
        Health = health;
    }

    //Damage Class
    public int TakeDamage(int damageAmount)
    {
        if(damageAmount > health)
        {
            damageAmount = health;
            return damageAmount;
        }
        else
        {
            health = health - damageAmount;
            return damageAmount;
        }
    }

    //Health Class
    public string GetHealthDisplay()
    {
        return "Health " + Health;
    }
}
}
solved 0
2 Answer 46 views 0

Answers ( 2 )

    0
    January 12, 2017 at 3:00 am

    Please briefly explain why you feel this answer should be reported .

    Report Cancel

    Actually, since name is common to all implementer of interface that Name property should be included to interface itself like

    interface ICombatant
    {
        int TakeDamage(int damageAmount);
        string GetHealthDisplay();
        public string CharacterName
        {
            get;
            set;
        }
    }
    

    In your current scenario, you will have to cast it specific concrete type before accessing it

    var character = combatants[i];
    if(character is PlayerCharacter)
       output += "Character:" + ((PlayerCharacter)character).CharacterName;
    
    Best answer
    0
    January 12, 2017 at 3:00 am

    Please briefly explain why you feel this answer should be reported .

    Report Cancel

    It’s better to make a good use of your interface. Create a new method in your interface:

    interface ICombatant
    {
        int TakeDamage(int damageAmount);
        string GetHealthDisplay();
        string GetCombatantName(); // added this
    }
    

    Then implement in both classes which implements it:

    class PlayerCharacter : ICombatant
    {
    
        // ... a lot of code ...
    
        public string GetCombatantName()
        {
            return String.Format("Character: {0}", this.CharacterName);
        }
    }
    
    class MonsterCharacter: ICombatant
    {
    
        // ... a lot of code ...
    
        public string GetCombatantName()
        {
            return String.Format("Monster: {0}", this.MonsterName);
        }
    
    }
    

    And use it like this:

    private void btnTest_Click(object sender, EventArgs e)
    {
        combatants[0] = new PlayerCharacter("Conan", 500);
        combatants[1] = new MonsterCharacter("Bob", 5);
        combatants[2] = new MonsterCharacter("Snake", 15);
    
        string output = "Fighters" + Environment.NewLine;
    
        foreach (var combatant in combatants)
        {
            output += combatant.GetCombatantName();
        }
    }
    

    So if one day you get ten distinct types of ICombatant (like AnimalCharacter, VirusCharacter), you don’t have to nest a lot of ifs to check and cast types to get the proper property.

    Interfaces are meant exactly to avoid this kind of stuff, hiding the implementation details.

Leave an answer

Browse

What is the capital of Egypt ? ( Cairo )

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>