Search code examples
c#xna-4.0

C# Access inherited class properties from list of base class


First, I create base class and inherited class

public class Entity
{
   public int EntityID;
   public EntityType type = EntityType.NONE;
}

public class EntityObject : Entity
{
   public Vector2 position;
   public EntityObject()
   {
      position = Vector2.Zero;
      type = EntityType.OBJECT;
   }
}

And then I create list of base class to store all inherited class

List<Entity> entityList = new List<Entity>();
entityList.Add(new EntityObject());

Later, I try to access a member of inherited class in list

for(int i = 0; i < entityList.Count; i++)
    if(entityList[i].type == EntityType.OBJECT)
        entityList[i].position = Vector2.One;

Yeah, I got an error : 'Entity' does not contain a definition for 'position'and no extension method 'position' accepting a first argument of type 'Entity' could be found (are you missing a using directive or an assembly reference?)

Is there a probably way to access inherited class properties from list of base class?


Solution

  • You need to cast the Entity instance to an EntityObject instance, because the Position field is indeed not part of Entity

    So:

    var entityObjectInEntityList = (EntityObject)entityList[0]
    

    Will give you the correct type, which you can then access the .Position field against.


    As mentioned in the comments, you could also test the type / do the cast the following ways:

    if(entityList[0] is EntityObject)
    

    Just testing type - usually avoided as you still need to cast to get the correct type and that involves overhead

    var item = entityList[0] as EntityObject;
    if (item != null)
    {
       var position = item.Position;
    }
    

    OR with C# 6

    var position = (entityList[0] as EntityObject)?.Position;
    

    Using the as keyword to perform a cast, and return a null if it fails.


    In the interests of mercy, as pointed out by Henk, you're clearly trying to include some type information in your class, in the form of the EntityType property.

    You can determine the type of an object at runtime:

    var type = instance.GetType();
    

    Therefore:

    if(itemInList.GetType() == typeof(EntityObject))
    

    will tell you the type of the instance, but using things like type checking of derived classes is often a smell.

    Assuming you don't need any base functionality on Entity I would recommend going with an interface approach instead.

    I'd recommend looking here: Interface vs Base class