Iterate over all instances of the base class and inherited classes

I have a base class called CollidableObject and several inherited classes called Player , Enemy , InertObject , etc.

I'm trying to find an easy way to repeat all instances, so I initially created a list of type CollidableObject and put all the instances of the inherited classes there.

The thing is, due to the nature of polymorphism, when I do the following

 foreach (CollidableObject CollidableObject in collidableObjects) { if (CollidableObject is Player) { CollidableObject.Draw(spriteBatch, testPlayerTexture); } // Then the same prodedure for each type of CollidableObject. // Might change to switch or something. } 

The draw method that it calls is the general Draw method from the CollidbaleObject base, not the overridden / new from the Player / Enemy / inert object.

How do I get around this. Is there a way to iterate through a collection of objects from a single tree, but preserve their inherited type?

+6
source share
3 answers

Is it impossible to iterate through a set of objects from one tree, but preserving your inherited type?

Absolutely, there is a way to do this. However, you need to set up your hierarchy correctly:

  • The Draw method in CollidableObject must be marked virtual
  • The Draw method in Player must be marked as override .

This ensures that the call from your message is redirected to the Player method override, and not to the base method.

In the corresponding note, when you see code that checks the dynamic type of an object using the is operator, as in if (CollidableObject is Player) , you should get strong suspicions that you are doing something wrong. For example, you may not have enough double sending .

If all you need to know is the correct texture for the type, you can put the textures in Dictionary<Type,Texture> textureForType and pull the right one in your loop using GetType() object that can be copied.

+9
source

You tried:

 foreach (CollidableObject CollidableObject in collidableObjects) { if (CollidableObject is Player) { ((Player) CollidableObject).Draw(spriteBatch, testPlayerTexture); } //Then the same prodedure for each type of CollidableObject. Might change to switch or something. } 
+4
source

I would have each class implement the Draw method specific to this class. They will need the same signature.

Then your foreach does not care about what class it really is, and will look like this

 foreach (CollidableObject CollidableObject in collidableObjects) { CollidableObject.Draw(....); } 

This will be the "Object Oriented" way to do this.

-1
source

All Articles