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();
}

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();
}
See more on this question at Stackoverflow