3

I have a problem where i have a list of one class (DrawableGameComponent) with many instances of different types of classes inherited from DrawableGameComponent.

The thing is i want to access a variable from one of those classes, but since they are declared as a DrawableGameComponent, i can't access any other variable than DrawableGameComponent has.

main class:

List<DrawableGameComponent> entities = new List<DrawableGameComponent>();

"player" class:

public Color color;
public int score;

any idea of how i can access these variables from the main class?

1
  • 3
    The base class should not need to access members of a child class. You should probably have the base class call an abstract method and let the child implement whatever logic needs the child class's members. Commented Feb 24, 2012 at 15:36

7 Answers 7

2

If DrawableGameComponent is base for Player you can do this:

foreach(DrawableGameComponent entity in entities)
{
    Player player = entity as Player;
    if(player != null)
    {
        Color col = player.color;
        int score = player.score;
    }
}

Beacause 'is', 'as' and casting are relatively expensive it is preferred to do it just once - as above.

Sign up to request clarification or add additional context in comments.

Comments

1

Ryan P's got the right of it. If you're sure that Player derives from DrawableGameComponent, you can cast the instance of DrawableGameComponent to Player as shown above.

However, consider that some of those DrawableGameComponent instances may be something other than Player. Perhaps Enemy, for instance. You don't say specifically what you're doing with the instance, but this sort of downcast usually represents a design problem.

Just something to consider.

Comments

1

It seems like your inheritance-model is wrong: if a variable (I assume Color in your example) is declared in all/most derived classes (like player, bot, opponent etc) it should be declared in the base class. Derived classes that dont use the Color can ignore it

Comments

0

Assuming these classes are in the same project (scope), you can use the following:

if (dgc is Player)
{
    (dgc as Player).color = Colors.Red;
}

3 Comments

@AskI.Nator Great! Since this answer was helpful, please accept it by clicking the checkmark next to it!
While this is technically correct, from a system design perspective it's a very bad idea to have a base class that is aware of derived classes and that act on such knowledge. If nothing else, it potentially breaks the "L of SOLID.
This is not optimal way of doing it - you cast the same thing twice ('is' also casts behind scenes)
0

the short answer is

if(entity[0] is Player)
{
   ((Player)entity[0]).color
}

Comments

0

I'm assuming you know that you can cast something like so:

Player p = (Player)entities[0];

So what I think you have is a design problem. You can always use the is operator to figure out if the entity is a Player but you may end up with problems down the road if you ahve too much RTTI going on. If its just this one instance, casting is a good choice because it's kind of necessary.

Comments

0

If you want to access properties defined in the inherited class then you need to cast it to that type. DrawableGameComponent type instances can only expose properties within it (or any type it inherits from eg system.object)

So if you have the following:

class Player : DrawableGameComponent  
{  
  public int MyWidth { get; set; }  
} 

Then you can only access the MyWidth property when you have a Player instance:

Player playerObj = dgcObj as Player;  
if (playerObj != null) Console.Write(playerObj.MyWidth);

Whereas the following won't work:

DrawableGameComponent dgcObj = new Player();  
dgcObj.MyWidth // no such property 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.