Why do I have to cast an inherited class when it's proven that it is the base class?

I have a class called BonusCell. It inherits the GameEntity class.

public class BonusCell : GameEntity
{
   public void GiveStats()
   {

   }
}

I have a class called Cell

public Cell
{
    public GameEntity gameEntity;
}

I have a game grid that has a 2 dimension array of Cell.

public class Board
{
    public Cell[,] grid;
}

Why do I have to cast BonusCell even if I am using an if is statement to verify that it is a BonusCell? I understand that board.grid[x,y].gameEntity is a type of GameEntity, but if that's true how can it also be true that it is BonusCell ?

if (board.grid[x, y].gameEntity is BonusCell)
{
     BonusCell bonusCell = (BonusCell)board.grid[x, y].gameEntity;
     bonusCell.GiveStats();
}
Jon Skeet
people
quotationmark

Why do I have to cast BonusCell even if I am using an if is statement to verify that it is a BonusCell?

Because the is operator doesn't change the compile-time type of the expression board.grid[x, y].gameEntity. (In this case, I guess it's possible that a different thread could even change the value of board.grid[x, y].gameEntity between evaluations, making it genuinely unsafe. Either way, the compiler doesn't try to infer anything from the if condition. If the language specification required this, it would make it much more complicated.)

An alternative approach is to use as and an extra local variable :

BonusCell bonusCell = board.grid[x, y].gameEntity as BonusCell;
if (bonusCell != null) 
{
    bonusCell.GiveStats();
}

people

See more on this question at Stackoverflow