I'm running into issues with being able to call functions/properties that are unique to the child class. I'm wondering if there is a way to do do something similar to the following:
public class Creature
{
public int HealthPoints {get; set;}
public string Name {get; set;}
public int AttackValue {get; set;}
public Creature();
}
public class Magical : Creature
{
public int Mana {get; set;}
}
So, in this rudimentary example, I'd have a list of Creatures and would need to be able to call from that the Mana property of any given Magical creature.
As you have surely seen in other answers, you can access the Mana
property of magical creatures as follows:
foreach (Creature creature in creatures)
{
if (creature is Magical magical)
{
// ... do something with 'magical.Mana' here...
}
}
Since we're talking about polymorphism already, you should know that if (x is SomeType) { .. }
can be a code smell. Let's say you indeed have a foreach
loop for processing all your creatures. It might then be better to create a virtual method in the base class, and do whatever you're doing inside the foreach
loop in that virtual method. You would then override the method in your Magical
class and thereby get rid of the if
statement.
Let's do an example. Let's say, all your creatures get hit and lose some energy. Normal creatures lose health points, while magical creatures lose mana:
public partial class Creature // rest of your class is omitted in this example
{
public virtual void TakeHit()
{
// whatever you had in your original foreach loop, e.g.:
HealthPoints--;
}
}
public partial class Magical : Creature
{
public override void TakeHit()
{
// ... any special processing for Magical creatures goes here, e.g.:
Mana--;
// (you could also call 'base.TakeHit()' in this method.)
}
}
Your original foreach
loop now becomes much simpler:
foreach (Creature creature in creatures)
{ // note: no more if statement -- The virtual method
creature.TakeHit(); // invocation now takes care of distinguising
} // different (sub-)types of Creatures!
I would like to recommend a very nice presentation on this very topic to you: Conditionals and Polymorphism.
So, in this rudimentary example, I'd have a list of Creatures and would need to be able to call from that the Mana property of any given Magical creature.
Yes, this is possible. Use Enumerable.OfType<T>
:
IEnumerable<Creature> creatures = new List<Creature>();
// populate creatures
var magicalCreatures = creatures.OfType<Magical>();
foreach(var magicalCreature in magicalCreatures) {
Console.WriteLine(magicalCreature.Mana);
}
You need to do a conversion to "Magical" at that point. For example:
Creature aCreature = GetMyCreature();
Magical asMagical = aCreature as Magical; // Using "as" operator..
if (asMagical != null)
Console.WriteLine(asMagical.Mana);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With