Home Can I use a main class object as a parameter to find the subclass object?

# Can I use a main class object as a parameter to find the subclass object?

Korosevar
1#
Korosevar Published in 2018-02-12 14:13:26Z
 I'm still kinda new at coding so I was wondering if/how this works? //a class with armor with subclasses to say what part of the body it go's public class Armor { //stuff that applies to all armor } public class HeadArmor : Armor { //stuff for HeadPieces only } public class ChestArmor : Armor { } //etc //the class that stores what armor is equiped public class MainCharacterEquipment { //the class of my maincharacter public MainCharacter HeroEquipment { get; set; } public HeadArmor HeadSlot { get; set; } public ChestArmor ChestSlot { get; set; } //etc //a constructor that sets all to null public void EquipArmor(Armor armor) { if (armor is HeadArmor) { HeadSlot = armor; //compile error } if (armor is ChestArmor) { ChestSlot = armor; //compile error -> Missing a cast? } //etc } }  If I do this it will ask if I'm missing a cast. From reading on this forum it seems that a subclass is a type of the mainclass but not the other way around. To solve this I could make a method for each subclass of armor. Instead of using (Armor armor) as a parameter, I would use the (HeadArmor headArmor), (ChestArmor chestArmor), etc... But that seems tedious. I also read that there is a difference between typeof() and is but I dont realy understand that either. Preferably I would just cast the object armor to its subclass. Of course, the if function should check whether its not already the subclass (if that makes sense) ps: There actualy are no instances of Armor objects. Only objects of subclasses are instantiated. (should it matter)
Scott Baldric
2#
Scott Baldric Reply to 2018-02-12 14:31:13Z
 You need to specify the same cast when you do the assignment. The compiler does not carry information through the if statement once the initial check has passed. In your code: if (armor is HeadArmor) // The compiler verifies this is HeadArmor { // The compiler does not carry the information forward. // It has no way of knowing, on this line, that armor is still HeadArmor. // For all it knows, armor could be ChestArmor which would be invalid. HeadArmor = armor; }  To fix the error, you need to update your code as follows: if (armor is HeadArmor) { HeadArmor = (HeadArmor)armor; // Lets the compiler know this is HeadArmor. }  Another option could be to use as to try and suss out the correct choice. var headArmor = armor as HeadArmor; if (headArmor != null) { HeadArmor = headArmor; } 
Fildor
3#
 I suggest a Visitor Pattern instead: public abstract class Armor { public abstract void Equip( MainCharacterEquipment mce ); } public class HeadArmor : Armor { public override void Equip( MainCharacterEquipment mce ) { mce.HeadSlot=this; } } public class ChestArmor : Armor { public override void Equip( MainCharacterEquipment mce ) { mce.ChestSlot=this; } }  Then your MainCharacterEquipment code boils down to: public void EquipArmor(Armor armor) { armor.Equip(this); }  This gets rid of "if-else" and if you later chose to add more types of armor and Slots, you don't need to touch that code. Just add another XXXXArmor class and it will go to the right slot.