当证明它是基类时,为什么我必须转换一个继承的类?

时间:2015-07-25 17:25:50

标签: c# casting

我有一个名为BonusCell的班级。它继承了GameEntity类。

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

   }
}

我有一个名为Cell

的班级
public Cell
{
    public GameEntity gameEntity;
}

我有一个游戏网格,其二维数组为Cell

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

为什么即使我使用BonusCell语句验证它是if is,我也必须投射BonusCell?我理解board.grid[x,y].gameEntityGameEntity的一种类型,但如果确实如此,它is BonusCell怎么也可以呢?

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

3 个答案:

答案 0 :(得分:5)

  

为什么即使我使用if is语句验证它是BonusCell,我还是要投加BonusCell?

因为is运算符不会更改表达式board.grid[x, y].gameEntity的编译时类型。 (在这种情况下,我猜可能不同的线程甚至可能在评估之间更改board.grid[x, y].gameEntity的值,使其真正不安全。无论哪种方式,编译器都不会尝试推断{{1}中的任何内容。如果语言规范要求这样做,那将使它变得更加复杂。)

另一种方法是使用if和一个额外的局部变量:

as

答案 1 :(得分:1)

BonusCell bonusCell = board.grid[x, y].gameEntity as BonusCell; if (bonusCell != null) { bonusCell.GiveStats(); } 只是一个返回布尔值的检查。编译器对此没有进一步的假设。即使您在gameEntity is BonusCell的后面输入一个条件代码块,但始终是gameEntity编译器并不关心。然后你必须转换为BonusCell,因为就编译器而言,你只需要BonusCell

答案 2 :(得分:1)

'' operator仅检查您指定的类型是实现还是扩展另一种类型。

因为GameEntity可以是许多类型的基类,所以您必须检查当前引用的实例是否为BonusCell,这样您就知道可以将其转换为BonusCell以访问BonusCell特定成员。

如果您只想访问GameEntity的成员,则无需进行强制检查。

您可以使用' as'运算符以强制转换并检查实例是否为BonusCell

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